Class: SafeDb::ToolBelt::CryptIO
- Inherits:
-
Object
- Object
- SafeDb::ToolBelt::CryptIO
- Defined in:
- lib/utils/ciphers/crypt.io.rb
Overview
CryptIO concentrates on injecting and ingesting crypt properties into and out of a key/value dictionary as well as injecting and ingesting cryptographic materials into and out of text files.
Cryptographic Properties
A crypt properties dictionary acts as output from every encryption event and input to every decryption event. The most common properties include
-
the symmetric key used for the encryption and decryption
-
the iv (initialization vector) that adds another dimension of strength
-
authorization data that thwarts switch attacks by tying context to content
-
the cipher algorithm, its implementation and its encryption strength
-
the various glue strings that allow related ciphertext to occupy a file
Why Pad?
Many ciphers (like Blowfish) constrains plain text lengths to multiples of 8 (or 16) and a common right pad with spaces strategy is employed as a workaround. safe does it diferently.
Why isn’t Space Padding Used?
If safe padded plaintext (ending in one or more spaces) with spaces, the decrypt phase (after right stripping spaces) would return plain text string shorter than the original.
Why Unusual Padding and Separators
Why does safe employ unusual strings for padding and separation.
The separator string must be unusual to make it unlikely for it to occur in any of the map’s key value pairs nor indeed the chunk of text being glued. Were this to happen, the separate and reconstitute phase may not accurately return the same two entities we are employed to unite.
So How is Padding Done?
Instead of single space padding - safe uses an unlikely 7 character padder which is repeated until the multiple is reached.
<-|@|->
So How is Padding Done?
The padder length must be a prime number or infinite loops could occur.
If the padder string is likely to occur in the plain text, another
padder (or strategy) should and could be employed.
Constant Summary collapse
- TEXT_PADDER =
The safe text padder. See the class description for an analysis of the use of this type of padder.
"<-|@|->"
- INNER_GLUE_STRING =
An unusual string that glues together an encryption dictionary and a chunk of base64 encoded and encrypted ciphertext. The string must be unusual enough to ensure it does not occur within the dictionary metadata keys or values.
"\n<-|@| < || safe inner crypt material axis || > |@|->\n\n"
- OUTER_GLUE_STRING =
An unusual string that glues together the asymmetrically encrypted outer encryption key with the outer crypted text.
"\n<-|@| < || safe outer crypt material axis || > |@|->\n\n"
- DICT_HEADER_NAME =
Text header for key-value pairs hash map that will be serialized.
"crypt.properties"
- DICT_CIPHER_NAME =
Name for the class of cipher employed.
"cipher.class"
- DICT_CRYPT_KEY =
Name for the Base64 encoded symmetric (lock/unlock) crypt key.
"encryption.key"
- DICT_CRYPT_IV =
Dictionary name for the encryption iv (initialization vector)
"encryption.iv"
- DICT_TEXT_DIGEST =
Dictionary name for the Base64 (urlsafe) encoded plaintext digest.
"plaintext.digest"
Class Method Summary collapse
-
.inner_crypt_deserialize(hash_map, text_block) ⇒ String
Deserialize an safe formatted text which contains an encryption properties dictionary (serialized in INI format) and a Base64 encoded crypt block which is the subject of the encryption dictionary.
-
.inner_crypt_serialize(hash_map, text_chunk) ⇒ String
Serialize and then unify a hash map and a textual chunk using a known but unusual separator string in a manner that protects content integrity during the serialize / deserialize process.
-
.outer_crypt_deserialize(os_material, top_block) ⇒ String
Given two blocks of text that were bounded together by the selfself.outer_crypt_serialize method we must return either the first block (true) or the second (false).
-
.outer_crypt_serialize(crypt_material_x, crypt_material_y) ⇒ String
Using an outer divider (glue) - attach the asymmetrically encrypted outer encryption key with the outer encrypted text.
Class Method Details
.inner_crypt_deserialize(hash_map, text_block) ⇒ String
Deserialize an safe formatted text which contains an encryption properties dictionary (serialized in INI format) and a Base64 encoded crypt block which is the subject of the encryption dictionary.
The crypt serialization used a specific “inner glue” as the string that separates the serialized key/value dictionary and the encoded textual block. We now employ this glue to split the serialized dictionary from the textual block.
155 156 157 158 159 160 161 162 163 164 165 166 167 168 |
# File 'lib/utils/ciphers/crypt.io.rb', line 155 def self.inner_crypt_deserialize hash_map, text_block raise ArgumentError, "Cannot populate a nil hash map." if hash_map.nil? assert_contains_glue text_block, INNER_GLUE_STRING serialized_map = text_block.split(INNER_GLUE_STRING).first.strip encoded64_text = text_block.split(INNER_GLUE_STRING).last.strip ini_props_hash = IniFile.new( :content => serialized_map ) encrypt_values = ini_props_hash[DICT_HEADER_NAME] hash_map.merge!( encrypt_values ) return Base64.decode64( encoded64_text ) end |
.inner_crypt_serialize(hash_map, text_chunk) ⇒ String
Serialize and then unify a hash map and a textual chunk using a known but unusual separator string in a manner that protects content integrity during the serialize / deserialize process.
This crypt serialization uses a specific “inner glue” as the string that separates the serialized key/value dictionary and the encoded textual block.
111 112 113 114 115 116 117 118 119 |
# File 'lib/utils/ciphers/crypt.io.rb', line 111 def self.inner_crypt_serialize hash_map, text_chunk nil_or_empty_hash = hash_map.nil? || hash_map.empty? raise ArgumentError, "Cannot serialize nil or empty properties." if nil_or_empty_hash ini_map = IniFile.new ini_map[ DICT_HEADER_NAME ] = hash_map return ini_map.to_s + INNER_GLUE_STRING + text_chunk end |
.outer_crypt_deserialize(os_material, top_block) ⇒ String
Given two blocks of text that were bounded together by the selfself.outer_crypt_serialize method we must return either the first block (true) or the second (false).
200 201 202 203 204 205 206 |
# File 'lib/utils/ciphers/crypt.io.rb', line 200 def self.outer_crypt_deserialize os_material, top_block assert_contains_glue os_material, OUTER_GLUE_STRING return os_material.split(OUTER_GLUE_STRING).first.strip if top_block return os_material.split(OUTER_GLUE_STRING).last.strip end |
.outer_crypt_serialize(crypt_material_x, crypt_material_y) ⇒ String
Using an outer divider (glue) - attach the asymmetrically encrypted outer encryption key with the outer encrypted text.
178 179 180 |
# File 'lib/utils/ciphers/crypt.io.rb', line 178 def self.outer_crypt_serialize crypt_material_x, crypt_material_y return crypt_material_x + OUTER_GLUE_STRING + crypt_material_y end |