# File lib/active_record/encryption/envelope_encryption_key_provider.rb, line 46 def primary_key_provider @primary_key_provider ||= DerivedSecretKeyProvider.new(ActiveRecord::Encryption.config.primary_key) end
class ActiveRecord::Encryption::EnvelopeEncryptionKeyProvider
Implements a simple envelope encryption approach where:
-
It generates a random data-encryption key for each encryption operation
-
It stores the generated key along with the encrypted payload. It encrypts this key with the master key provided in the credential +active_record.encryption.master key+
This provider can work with multiple master keys. It will use the last one for encrypting.
When ‘config.store_key_references` is true, it will also store a reference to the specific master key that was used to encrypt the data-encryption key. When not set, it will try all the configured master keys looking for the right one, in order to return the right decryption key.
Public Instance Methods
active_primary_key()
click to toggle source
# File lib/active_record/encryption/envelope_encryption_key_provider.rb, line 31 def active_primary_key @active_primary_key ||= primary_key_provider.encryption_key end
decryption_keys(encrypted_message)
click to toggle source
# File lib/active_record/encryption/envelope_encryption_key_provider.rb, line 26 def decryption_keys(encrypted_message) secret = decrypt_data_key(encrypted_message) secret ? [ActiveRecord::Encryption::Key.new(secret)] : [] end
encryption_key()
click to toggle source
# File lib/active_record/encryption/envelope_encryption_key_provider.rb, line 18 def encryption_key random_secret = generate_random_secret ActiveRecord::Encryption::Key.new(random_secret).tap do |key| key.public_tags.encrypted_data_key = encrypt_data_key(random_secret) key.public_tags.encrypted_data_key_id = active_primary_key.id if ActiveRecord::Encryption.config.store_key_references end end
Private Instance Methods
decrypt_data_key(encrypted_message)
click to toggle source
# File lib/active_record/encryption/envelope_encryption_key_provider.rb, line 40 def decrypt_data_key(encrypted_message) encrypted_data_key = encrypted_message.headers.encrypted_data_key key = primary_key_provider.decryption_keys(encrypted_message)&.collect(&:secret) ActiveRecord::Encryption.cipher.decrypt encrypted_data_key, key: key if key end
encrypt_data_key(random_secret)
click to toggle source
# File lib/active_record/encryption/envelope_encryption_key_provider.rb, line 36 def encrypt_data_key(random_secret) ActiveRecord::Encryption.cipher.encrypt(random_secret, key: active_primary_key.secret) end
generate_random_secret()
click to toggle source
# File lib/active_record/encryption/envelope_encryption_key_provider.rb, line 50 def generate_random_secret ActiveRecord::Encryption.key_generator.generate_random_key end
primary_key_provider()
click to toggle source