Class: SafeDb::Key64
- Inherits:
-
Object
- Object
- SafeDb::Key64
- Defined in:
- lib/utils/keys/key.64.rb
Overview
First use the class methods to source keys, then use a key’s instance methods to access its properties and in concert with other symmetrical information, you can use the keys to lock (encrypt) or unlock (decrypt) other keys and objects.
Sourcing and Deriving Keys
Keys can be
-
sourced from a secure random byte generating function
-
sourced from ciphertext and another (decryption) key
-
generated by passing a secret through key derivation functions
-
regenerated from a secret and previously stored salts
-
sourced from the current unique workstation shell environment
-
sourced from an environment variable containing ciphertext
Keys need to be viewed (represented) in multiple ways and the essence of the key viewer is to input keys as_bits, as_bytes and as_base64 and then output the same key (in as far as is possible) - as bits, as bytes and as base64.
Key | To and From Behaviour
Use the From methods to create Keys from a variety of resources such as
-
a base64 encoded string
-
a binary byte string
-
a string of one and zero bits
-
a hexadecimal representation
Once you have instantiated the key, you will then be able to convert it (within reason due to bit, byte and base64 lengths) to any of the above key representations.
Key | Bits Bytes and Base64
The shoe doesn’t always fit when its on the other foot and this is best illustratd with a table that maps bits to 8 bit bytes and 6 bit Base64 characters.
| --------- | -------- | ------------ | ------------------------------- |
| Fit? | Bits | Bytes | (and) Base64 |
| --------- | -------- | ------------ | ------------------------------- |
| Perfect | 168 Bits | is 21 bytes | 28 Chars - bcrypt chops to this |
| Perfect | 216 Bits | is 27 bytes | 36 Chars - |
| Perfect | 264 Bits | is 33 bytes | 44 Chars - holder 4 256bit keys |
| Perfect | 384 Bits | is 48 bytes | 64 Chars - 216 + 168 equals 384 |
| --------- | -------- | ------------ | ------------------------------- |
| Imperfect | 128 Bits | 16 precisely | 22 Chars - 21 + 2 remain bits |
| Imperfect | 186 Bits | 23 remain 2 | 31 Characers precisely |
| Imperfect | 256 Bits | 32 precisely | 43 Chars - 42 + 4 remain bits |
| --------- | -------- | ------------ | ------------------------------- |
Yes, the shoe doesn’t always fit when it’s on the other foot.
Schoolboy Error
The strategy is so simple, we call it a schoolboy error.
If we want to use a key with n bits and either n % 6 or n % 8 (or both) are not zero - we instantiate a Key with the lowest common denominator of 6 and 8 that exceeds n.
So when we request a byte, or base64 representation the viewer will truncate (not round down) to the desired length.
YACHT 64 | Yet Another Character Table
This binary key class is a dab hand at converting base64 strings into their 6-bit binary string equivalents.
It can convert non-alphanumeric characters within either Base64 or Radix64 into the SafeDb YACHT64 standard which has a forward slash but neither a plus sign nor a period character.
The Big4 Character Sets | Base64 | UrlSafe64 | Radix64 | YACHT64
Base64 and Radix64 (from OpenBSD) differ in both the order of characters and their choice of the two non-alphanumeric characters. Base64 can also contain line breaks and equal signs for padding. UrlSafe base64 has different choices for the two non alphanum characters in keeping with URL standards.
The character sets for each of the four 64 fomats are as follows.
-
Base-64 is A to Z then a to z then 0 to 9 then + then /
-
Radix64 is . then / then 0 to 9 then A to Z then a to z
-
UrlSafeBase64 is Base64 but chars 63/64 are an underscore (_) and hyphen (-)
-
UrlSafeBase64 does not have line breaks and carriage returns (unlike Base64)
-
SafeDb 64 (YACHT64) uses the same 62 characters plus an @ sign and a forward slash
-
The 64 SafeDb 64 characters are obfuscated into a random order
4 Non-AlphaNumerics | Base64 | Radix64 | YACHT64
The behaviour here is happy to convert base64 strings produced by either Radix64 or Base64 or UrlSafe Base64. Howeverr it aware of the non alpha-numeric characters and converts them before processing with the modus operandi that says
-
ignore the forward slash in YACHT64, Base64 and Radix64
-
convert the plus (+) in Base64 to the @ symbol in YACHT64
-
convert the period (.) in Radix64 to the @ symbol in YACHT64
-
convert hyphen (-) in Url Safe Base64 into a fwd slash
-
convert underscore (_) in Url Safe Base64 to an @ sign
-
delete the (=) equals padding character used by Base64
Neither the OpenBSD backed Radix64 nor the SafeDb (YACHT64) entertain the concept of padding.
Mapping Each Character to 6 Binary Bits
We need 6 binary bits to represent a base64 character (and 4 bits for hexadecimal). Here is an example mapping between a base 64 character, an integer and the six bit binary.
Character Integer Binary (6 Bit)
a 0 000000
b 1 000001
c 2 000010
y 25 011001
z 26 011010
A 27 011011
B 28 011100
8 60 111100
9 61 111101
/ 62 111110
+ 63 111111
Constant Summary collapse
- YACHT64_CHARACTER_SET =
YACHT stands for Yet Another Character Table and it can map binary sequences onto 64 well chosen characters.
The 64 character sets are all similar in that they hold 64 characters and they define two non alphanumeric characters because the 26 lowercase, 26 uppercase and 10 digits only adds up to an agonisingly close 62 characters.
[ "a", "9", "W", "B", "f", "K", "O", "z", "3", "s", "1", "5", "c", "n", "E", "J", "L", "A", "l", "6", "I", "w", "o", "g", "k", "N", "t", "Y", "S", "%", "T", "b", "V", "R", "H", "0", "@", "Z", "8", "F", "G", "j", "u", "m", "M", "h", "4", "p", "q", "d", "7", "v", "e", "2", "U", "X", "r", "C", "y", "Q", "D", "x", "P", "i" ]
- PERIOD =
Radix64 strings can contain period characters in their midst.
"."
- FORWARD_SLASH =
Radix64 strings can contain forward slashes in their midst.
"/"
- AT_SYMBOL =
YACHT64 strings can contain at symbols in their midst.
"@"
- PERCENT_SIGN =
YACHT64 strings can contain percent signs in their midst.
"%"
Class Method Summary collapse
-
.from_bits(bit_string) ⇒ String
Convert the parameter string of ones and zeroes into an internal base64 character set known as YACHT for yet another character table.
-
.from_radix64_to_bits(radix64_string) ⇒ String
Convert a string of Radix64 characters into a bit representation which will be 6 times longer than the input parameter.
-
.to_bits(char64_string) ⇒ String
Convert the parameter characters based on an internal base64 character set (known as YACHT) into a bit string of ones and zeroes.
Class Method Details
.from_bits(bit_string) ⇒ String
Convert the parameter string of ones and zeroes into an internal base64 character set known as YACHT for yet another character table.
190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 |
# File 'lib/utils/keys/key.64.rb', line 190 def self.from_bits bit_string nil_err_msg = "The parameter bit string cannot be nil." raise ArgumentError, nil_err_msg if bit_string.nil? bit_size_msg = "The bit string length is not a multiple of #{SIX}." raise ArgumentError, bit_size_msg unless bit_string.length % SIX == 0 num_unknowns = bit_string.delete("10").length unknowns_msg = "The bit string has #{num_unknowns} characters that are not 1 or 0." raise ArgumentError, unknowns_msg if num_unknowns > 0 characters64 = "" char_count = bit_string.length / SIX for n in 0 .. (char_count-1) six_bit_chunk = bit_string[ (n*SIX), SIX ] six_bit_index = six_bit_chunk.to_i(2) characters64 += Key64.character(six_bit_index) end code_size_msg = "Length is #{characters64.length} but #{char_count} is expected." raise RuntimeError, code_size_msg unless characters64.length == char_count return characters64 end |
.from_radix64_to_bits(radix64_string) ⇒ String
Convert a string of Radix64 characters into a bit representation which will be 6 times longer than the input parameter. This method first converts the string into the internal YACHT64 format and then converts that to a bit string using the to_bits method.
275 276 277 278 279 280 281 282 |
# File 'lib/utils/keys/key.64.rb', line 275 def self.from_radix64_to_bits radix64_string yacht64_chars = radix64_string.gsub( PERIOD, AT_SYMBOL ).gsub( FORWARD_SLASH, PERCENT_SIGN ) out_bitstring = to_bits( yacht64_chars ) assert_bit_lengths( radix64_string, out_bitstring ) return out_bitstring end |
.to_bits(char64_string) ⇒ String
Convert the parameter characters based on an internal base64 character set (known as YACHT) into a bit string of ones and zeroes.
242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 |
# File 'lib/utils/keys/key.64.rb', line 242 def self.to_bits char64_string bit_string = "" char64_string.each_char do |the_char| yacht64_index = YACHT64_CHARACTER_SET.index(the_char) assert_yacht64_index( the_char, yacht64_index ) bit_string += "%06d" % [ yacht64_index.to_s(2) ] end assert_bit_lengths char64_string, bit_string return bit_string end |