Class: Darrrr::EncryptedData
- Inherits:
-
Object
- Object
- Darrrr::EncryptedData
- Extended by:
- Forwardable
- Defined in:
- lib/darrrr/cryptors/default/encrypted_data.rb
Constant Summary collapse
- CIPHER_OPTIONS =
[:encrypt, :decrypt].freeze
- CIPHER =
"aes-256-gcm".freeze
- CIPHER_VERSION =
0
- IV_LENGTH =
This is the NIST recommended minimum: nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38d.pdf
12
- AUTH_TAG_LENGTH =
16
- PROTOCOL_VERSION =
0
Instance Attribute Summary collapse
-
#token_object ⇒ Object
readonly
Returns the value of attribute token_object.
Class Method Summary collapse
-
.build(data) ⇒ Object
data: the value to encrypt.
-
.cipher(mode) ⇒ Object
DRY helper for generating cipher objects.
-
.parse(serialized_data) ⇒ Object
serialized_data: the binary representation of a token.
Instance Method Summary collapse
- #decrypt ⇒ Object
-
#initialize(token_object) ⇒ EncryptedData
constructor
token_object: an EncryptedDataIO instance instance.
Constructor Details
#initialize(token_object) ⇒ EncryptedData
token_object: an EncryptedDataIO instance instance.
21 22 23 24 25 26 |
# File 'lib/darrrr/cryptors/default/encrypted_data.rb', line 21 def initialize(token_object) raise TokenFormatError, "Version must be #{PROTOCOL_VERSION}. Supplied: #{token_object.version}" unless token_object.version == CIPHER_VERSION raise TokenFormatError, "Auth Tag must be 16 bytes" unless token_object.auth_tag.length == AUTH_TAG_LENGTH raise TokenFormatError, "IV must be 12 bytes" unless token_object.iv.length == IV_LENGTH @token_object = token_object end |
Instance Attribute Details
#token_object ⇒ Object (readonly)
Returns the value of attribute token_object.
14 15 16 |
# File 'lib/darrrr/cryptors/default/encrypted_data.rb', line 14 def token_object @token_object end |
Class Method Details
.build(data) ⇒ Object
data: the value to encrypt.
returns an EncryptedData instance.
43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
# File 'lib/darrrr/cryptors/default/encrypted_data.rb', line 43 def build(data) cipher = cipher(:encrypt) iv = SecureRandom.random_bytes(EncryptedData::IV_LENGTH) cipher.iv = iv cipher.auth_data = "" ciphertext = cipher.update(data.to_s) + cipher.final token = EncryptedDataIO.new.tap do |edata| edata.version = CIPHER_VERSION edata.auth_tag = cipher.auth_tag.bytes edata.iv = iv.bytes edata.ciphertext = ciphertext.bytes end new(token) end |
.cipher(mode) ⇒ Object
DRY helper for generating cipher objects
78 79 80 81 82 83 84 85 86 87 |
# File 'lib/darrrr/cryptors/default/encrypted_data.rb', line 78 def cipher(mode) unless CIPHER_OPTIONS.include?(mode) raise ArgumentError, "mode must be `encrypt` or `decrypt`" end OpenSSL::Cipher.new(EncryptedData::CIPHER).tap do |cipher| cipher.send(mode) cipher.key = [Darrrr.this_account_provider.instance_variable_get(:@symmetric_key)].pack("H*") end end |
.parse(serialized_data) ⇒ Object
serialized_data: the binary representation of a token.
returns an EncryptedData instance.
64 65 66 67 68 69 70 71 72 73 74 75 |
# File 'lib/darrrr/cryptors/default/encrypted_data.rb', line 64 def parse(serialized_data) data = new(EncryptedDataIO.new.read(serialized_data)) # be extra paranoid, oracles and stuff if data.num_bytes != serialized_data.bytesize raise CryptoError, "Encypted data field includes unexpected extra bytes" end data rescue IOError => e raise RecoveryTokenSerializationError, e. end |
Instance Method Details
#decrypt ⇒ Object
29 30 31 32 33 34 35 36 37 |
# File 'lib/darrrr/cryptors/default/encrypted_data.rb', line 29 def decrypt cipher = self.class.cipher(:decrypt) cipher.iv = self.iv.to_binary_s cipher.auth_tag = self.auth_tag.to_binary_s cipher.auth_data = "" cipher.update(self.ciphertext.to_binary_s) + cipher.final rescue OpenSSL::Cipher::CipherError => e raise CryptoError, "Unable to decrypt data: #{e}" end |