Class: Dry::Credentials::Encryptor
- Inherits:
-
Object
- Object
- Dry::Credentials::Encryptor
- Defined in:
- lib/dry/credentials/encryptor.rb
Constant Summary collapse
- DEFAULT_CIPHER =
'aes-256-gcm'
- DEFAULT_DIGEST =
'sha256'
- DEFAULT_SERIALIZER =
Marshal
- SEPARATOR =
'--'
Instance Method Summary collapse
-
#decrypt(encrypted_object, key:) ⇒ Object
Decrypts the encrypted object.
-
#encrypt(object, key:) ⇒ String
Encrypts the object.
-
#generate_key ⇒ String
Generate a random key with the length required by the current cipher, then Base64 encodes and unpacks all bytes to hex.
-
#initialize(cipher: DEFAULT_CIPHER, digest: DEFAULT_DIGEST, serializer: DEFAULT_SERIALIZER) ⇒ Encryptor
constructor
A new instance of Encryptor.
Constructor Details
#initialize(cipher: DEFAULT_CIPHER, digest: DEFAULT_DIGEST, serializer: DEFAULT_SERIALIZER) ⇒ Encryptor
Returns a new instance of Encryptor.
18 19 20 21 |
# File 'lib/dry/credentials/encryptor.rb', line 18 def initialize(cipher: DEFAULT_CIPHER, digest: DEFAULT_DIGEST, serializer: DEFAULT_SERIALIZER) @cipher = OpenSSL::Cipher.new(cipher) @digest, @serializer = digest, serializer end |
Instance Method Details
#decrypt(encrypted_object, key:) ⇒ Object
Decrypts the encrypted object
60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
# File 'lib/dry/credentials/encryptor.rb', line 60 def decrypt(encrypted_object, key:) @cipher.decrypt @cipher.key = decoded_key = decode(pack(key.strip)) payload, iv, auth_tag = encrypted_object.strip.split(SEPARATOR) if auth_tag.nil? || (aead? && decode(auth_tag).bytes.length != auth_tag_length) || (!aead? && hmac(decoded_key, payload + SEPARATOR + iv) != auth_tag) then fail Dry::Credentials::InvalidEncryptedObjectError end @cipher.iv = decode(iv) if aead? @cipher.auth_tag = decode(auth_tag) @cipher.auth_data = '' end @cipher.update(decode(payload)).then do |data| data << @cipher.final @serializer.load(data) end rescue OpenSSL::Cipher::CipherError, TypeError, ArgumentError raise Dry::Credentials::InvalidEncryptedObjectError end |
#encrypt(object, key:) ⇒ String
Encrypts the object
Relies on encrypted authenticated encryption mode if available for the selected cipher. Otherwise, the encrypted string is HMAC signed.
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
# File 'lib/dry/credentials/encryptor.rb', line 39 def encrypt(object, key:) @cipher.encrypt @cipher.key = decoded_key = decode(pack(key.strip)) iv = @cipher.random_iv @cipher.auth_data = '' if aead? @cipher.update(@serializer.dump(object)).then do |data| data << @cipher.final data = encode(data) + SEPARATOR + encode(iv) data << SEPARATOR + if aead? encode(@cipher.auth_tag) else hmac(decoded_key, data) end end end |
#generate_key ⇒ String
Generate a random key with the length required by the current cipher, then Base64 encodes and unpacks all bytes to hex.
27 28 29 |
# File 'lib/dry/credentials/encryptor.rb', line 27 def generate_key unpack(encode(SecureRandom.bytes(@cipher.key_len))) end |