Class: SymmetricEncryption::Header
- Inherits:
-
Object
- Object
- SymmetricEncryption::Header
- Defined in:
- lib/symmetric_encryption/header.rb
Overview
Defines the Header Structure returned when parsing the header.
Note:
-
Header only works against binary encrypted data that has not been decoded.
-
Decode data first before trying to extract its header.
-
Decoding is not required when encoding is set to ‘:none`.
Constant Summary collapse
- MAGIC_HEADER =
Encrypted data includes this header prior to encoding when ‘always_add_header` is true.
"@EnC".force_encoding(SymmetricEncryption::BINARY_ENCODING)
- MAGIC_HEADER_SIZE =
MAGIC_HEADER.size
Instance Attribute Summary collapse
-
#auth_tag ⇒ Object
readonly
- String
-
Binary auth tag used to encrypt the data.
-
#cipher_name ⇒ Object
- String
-
Name of the cipher used.
-
#compress ⇒ Object
- true|false
-
Whether to compress the data before encryption.
-
#iv ⇒ Object
- String
-
IV used to encrypt the data.
-
#key ⇒ Object
- String
-
Key used to encrypt the data.
-
#version ⇒ Object
- Integer
-
Version of the cipher used.
Class Method Summary collapse
-
.present?(buffer) ⇒ Boolean
Returns whether the supplied buffer starts with a symmetric_encryption header Note: The encoding of the supplied buffer is forced to binary if not already binary.
Instance Method Summary collapse
-
#cipher ⇒ Object
Returns [SymmetricEncryption::Cipher] the cipher used to decrypt or encrypt the key specified in this header, if supplied.
- #compressed? ⇒ Boolean
-
#initialize(version: SymmetricEncryption.cipher.version, compress: false, iv: nil, key: nil, cipher_name: nil, auth_tag: nil) ⇒ Header
constructor
Returns a magic header for this cipher instance that can be placed at the beginning of a file or stream to indicate how the data was encrypted.
-
#parse(buffer, offset = 0) ⇒ Object
Returns [Integer] the offset within the buffer of the data after the header has been read.
-
#parse!(buffer) ⇒ Object
Returns [String] the encrypted data without header Returns nil if no header is present.
-
#to_s ⇒ Object
Returns [String] this header as a string.
Constructor Details
#initialize(version: SymmetricEncryption.cipher.version, compress: false, iv: nil, key: nil, cipher_name: nil, auth_tag: nil) ⇒ Header
Returns a magic header for this cipher instance that can be placed at the beginning of a file or stream to indicate how the data was encrypted
Parameters
compress [true|false]
Whether the data should be compressed before encryption.
Default: false
iv [String]
The iv to to put in the header
Default: nil : Exclude from header
key [String]
The key to to put in the header.
The key is encrypted using the global encryption key
Default: nil : Exclude key from header
version: [Integer (0..255)]
Version of the global cipher used to encrypt the data,
or the encryption key if supplied.
default: The current global encryption cipher version.
cipher_name [String]
The cipher_name to be used for encrypting the data portion.
For example 'aes-256-cbc'
`key` if supplied is encrypted with the cipher name based on the cipher version in this header.
Intended for use when encrypting large files with a different cipher to the global one.
Default: nil : Exclude cipher_name name from header
74 75 76 77 78 79 80 81 82 83 84 85 86 87 |
# File 'lib/symmetric_encryption/header.rb', line 74 def initialize(version: SymmetricEncryption.cipher.version, compress: false, iv: nil, key: nil, cipher_name: nil, auth_tag: nil) @version = version @compress = compress @iv = iv @key = key @cipher_name = cipher_name @auth_tag = auth_tag end |
Instance Attribute Details
#auth_tag ⇒ Object
- String
-
Binary auth tag used to encrypt the data.
Usually 16 bytes. Present when using an authenticated encryption mode.
35 36 37 |
# File 'lib/symmetric_encryption/header.rb', line 35 def auth_tag @auth_tag end |
#cipher_name ⇒ Object
- String
-
Name of the cipher used.
27 28 29 |
# File 'lib/symmetric_encryption/header.rb', line 27 def cipher_name @cipher_name end |
#compress ⇒ Object
- true|false
-
Whether to compress the data before encryption.
If supplied in the header.
16 17 18 |
# File 'lib/symmetric_encryption/header.rb', line 16 def compress @compress end |
#iv ⇒ Object
- String
-
IV used to encrypt the data.
If supplied in the header.
20 21 22 |
# File 'lib/symmetric_encryption/header.rb', line 20 def iv @iv end |
#key ⇒ Object
- String
-
Key used to encrypt the data.
If supplied in the header.
24 25 26 |
# File 'lib/symmetric_encryption/header.rb', line 24 def key @key end |
#version ⇒ Object
- Integer
-
Version of the cipher used.
30 31 32 |
# File 'lib/symmetric_encryption/header.rb', line 30 def version @version end |
Class Method Details
.present?(buffer) ⇒ Boolean
Returns whether the supplied buffer starts with a symmetric_encryption header Note: The encoding of the supplied buffer is forced to binary if not already binary
39 40 41 42 43 44 |
# File 'lib/symmetric_encryption/header.rb', line 39 def self.present?(buffer) return false if buffer.nil? || (buffer == "") buffer.force_encoding(SymmetricEncryption::BINARY_ENCODING) buffer.start_with?(MAGIC_HEADER) end |
Instance Method Details
#cipher ⇒ Object
Returns [SymmetricEncryption::Cipher] the cipher used to decrypt or encrypt the key specified in this header, if supplied.
91 92 93 |
# File 'lib/symmetric_encryption/header.rb', line 91 def cipher @cipher ||= SymmetricEncryption.cipher(version) end |
#compressed? ⇒ Boolean
100 101 102 |
# File 'lib/symmetric_encryption/header.rb', line 100 def compressed? @compress end |
#parse(buffer, offset = 0) ⇒ Object
Returns [Integer] the offset within the buffer of the data after the header has been read.
Returns 0 if no header is present
124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 |
# File 'lib/symmetric_encryption/header.rb', line 124 def parse(buffer, offset = 0) return 0 if buffer.nil? || (buffer == "") || (buffer.length <= MAGIC_HEADER_SIZE + 2) # Symmetric Encryption Header # # Consists of: # 4 Bytes: Magic Header Prefix: @Enc # 1 Byte: The version of the cipher used to encrypt the header. # 1 Byte: Flags: # Bit 1: Whether the data is compressed # Bit 2: Whether the IV is included # Bit 3: Whether the Key is included # Bit 4: Whether the Cipher Name is included # Bit 5: Future use # Bit 6: Future use # Bit 7: Future use # Bit 8: Future use # 2 Bytes: IV Length (little endian), if included. # IV in binary form. # 2 Bytes: Key Length (little endian), if included. # Key in binary form # 2 Bytes: Cipher Name Length (little endian), if included. # Cipher name it UTF8 text buffer.force_encoding(SymmetricEncryption::BINARY_ENCODING) header = buffer.byteslice(offset, MAGIC_HEADER_SIZE) return 0 unless header == MAGIC_HEADER offset += MAGIC_HEADER_SIZE # Remove header and extract flags self.version = buffer.getbyte(offset) offset += 1 unless cipher raise( SymmetricEncryption::CipherError, "Cipher with version:#{version.inspect} not found in any of the configured SymmetricEncryption ciphers" ) end flags = buffer.getbyte(offset) offset += 1 self.compress = (flags & FLAG_COMPRESSED) != 0 if (flags & FLAG_IV).zero? self.iv = nil else self.iv, offset = read_string(buffer, offset) end if (flags & FLAG_KEY).zero? self.key = nil else encrypted_key, offset = read_string(buffer, offset) self.key = cipher.binary_decrypt(encrypted_key) end if (flags & FLAG_CIPHER_NAME).zero? self.cipher_name = nil else self.cipher_name, offset = read_string(buffer, offset) end if (flags & FLAG_AUTH_TAG).zero? self.auth_tag = nil else self.auth_tag, offset = read_string(buffer, offset) end offset end |
#parse!(buffer) ⇒ Object
Returns [String] the encrypted data without header Returns nil if no header is present
The supplied buffer will be updated directly and its header will be stripped if present.
Parameters
buffer
String to extract the header from
113 114 115 116 117 118 119 |
# File 'lib/symmetric_encryption/header.rb', line 113 def parse!(buffer) offset = parse(buffer) return if offset.zero? buffer.slice!(0..offset - 1) buffer end |
#to_s ⇒ Object
Returns [String] this header as a string
199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 |
# File 'lib/symmetric_encryption/header.rb', line 199 def to_s flags = 0 flags |= FLAG_COMPRESSED if compressed? flags |= FLAG_IV if iv flags |= FLAG_KEY if key flags |= FLAG_CIPHER_NAME if cipher_name flags |= FLAG_AUTH_TAG if auth_tag header = "#{MAGIC_HEADER}#{version.chr(SymmetricEncryption::BINARY_ENCODING)}#{flags.chr(SymmetricEncryption::BINARY_ENCODING)}" if iv header << [iv.length].pack("v") header << iv end if key encrypted = cipher.binary_encrypt(key, header: false) header << [encrypted.length].pack("v") header << encrypted end if cipher_name header << [cipher_name.length].pack("v") header << cipher_name end if auth_tag header << [auth_tag.length].pack("v") header << auth_tag end header end |