module AttrVault::Cryptor
Public Class Methods
decrypt(encrypted, key)
click to toggle source
# File lib/attr_vault/cryptor.rb, line 18 def self.decrypt(encrypted, key) return encrypted if encrypted.nil? || encrypted.empty? secret = AttrVault::Secret.new(key) hmac, encrypted_payload = encrypted[0...32], encrypted[32..-1] expected_hmac = Encryption.hmac_digest(secret.signing_key, encrypted_payload) unless verify_signature(expected_hmac, hmac) raise InvalidCiphertext, "Expected hmac #{Base64.encode64(expected_hmac)} for this value; " + "got #{Base64.encode64(hmac)}" end iv, encrypted_message = encrypted_payload[0...16], encrypted_payload[16..-1] block_size = Encryption::AES_BLOCK_SIZE unless (encrypted_message.size % block_size).zero? raise InvalidCiphertext, "Expected message size to be multiple of #{block_size}; got #{encrypted_message.size}" end begin Encryption.decrypt(key: secret.encryption_key, ciphertext: encrypted_message, iv: iv) rescue OpenSSL::Cipher::CipherError raise InvalidCiphertext, "Could not decrypt field" end end
encrypt(value, key)
click to toggle source
# File lib/attr_vault/cryptor.rb, line 6 def self.encrypt(value, key) return value if value.nil? || value.empty? secret = AttrVault::Secret.new(key) encrypted_message, iv = Encryption.encrypt(key: secret.encryption_key, message: value) encrypted_payload = iv + encrypted_message mac = Encryption.hmac_digest(secret.signing_key, encrypted_payload) Sequel.blob(mac + encrypted_payload) end
Private Class Methods
verify_signature(expected, actual)
click to toggle source
# File lib/attr_vault/cryptor.rb, line 49 def self.verify_signature(expected, actual) expected_bytes = expected.bytes.to_a actual_bytes = actual.bytes.to_a actual_bytes.inject(0) do |accum, byte| accum |= byte ^ expected_bytes.shift end.zero? end