class ActiveRecord::Encryption::EnvelopeEncryptionKeyProvider

Implements a simple envelope encryption approach where:

This provider can work with multiple master keys. It will use the last one for encrypting.

When config.active_record.encryption.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
# 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