diff --git a/activerecord/lib/active_record/encryption/cipher.rb b/activerecord/lib/active_record/encryption/cipher.rb index 8bd2efb87f..c4ab197b9f 100644 --- a/activerecord/lib/active_record/encryption/cipher.rb +++ b/activerecord/lib/active_record/encryption/cipher.rb @@ -7,21 +7,21 @@ module ActiveRecord # It uses AES-256-GCM. It will generate a random IV for non deterministic encryption (default) # or derive an initialization vector from the encrypted content for deterministic encryption. # - # See +Cipher::Aes256Gcm+ + # See +Cipher::Aes256Gcm+. class Cipher DEFAULT_ENCODING = Encoding::UTF_8 - # Encrypts the provided text and return an encrypted +Message+ + # Encrypts the provided text and return an encrypted +Message+. def encrypt(clean_text, key:, deterministic: false) cipher_for(key, deterministic: deterministic).encrypt(clean_text).tap do |message| message.headers.encoding = clean_text.encoding.name unless clean_text.encoding == DEFAULT_ENCODING end end - # Decrypt the provided +Message+ + # Decrypt the provided +Message+. # # When +key+ is an Array, it will try all the keys raising a - # +ActiveRecord::Encryption::Errors::Decryption+ if none works + # +ActiveRecord::Encryption::Errors::Decryption+ if none works. def decrypt(encrypted_message, key:) try_to_decrypt_with_each(encrypted_message, keys: Array(key)).tap do |decrypted_text| decrypted_text.force_encoding(encrypted_message.headers.encoding || DEFAULT_ENCODING) diff --git a/activerecord/lib/active_record/encryption/cipher/aes256_gcm.rb b/activerecord/lib/active_record/encryption/cipher/aes256_gcm.rb index 08fc9d5e18..b77b788064 100644 --- a/activerecord/lib/active_record/encryption/cipher/aes256_gcm.rb +++ b/activerecord/lib/active_record/encryption/cipher/aes256_gcm.rb @@ -6,16 +6,11 @@ require "base64" module ActiveRecord module Encryption class Cipher - # A 256-GCM cipher - # - # This code is extracted from +ActiveSupport::MessageEncryptor+. Not using it directly because we want to control - # the message format and only serialize things once at the +ActiveRecord::Encryption::Message+ level. Also, this - # cipher is prepared to deal with deterministic/non deterministic encryption modes. + # A 256-GCM cipher. # # By default it will use random initialization vectors. For deterministic encryption, it will use a SHA-256 hash of # the text to encrypt and the secret. # - # See https://3.basecamp.com/2914079/buckets/14968485/todos/2426424308 # See +Encryptor+ class Aes256Gcm CIPHER_TYPE = "aes-256-gcm" @@ -38,6 +33,10 @@ module ActiveRecord end def encrypt(clear_text) + # This code is extracted from +ActiveSupport::MessageEncryptor+. Not using it directly because we want to control + # the message format and only serialize things once at the +ActiveRecord::Encryption::Message+ level. Also, this + # cipher is prepared to deal with deterministic/non deterministic encryption modes. + cipher = OpenSSL::Cipher.new(CIPHER_TYPE) cipher.encrypt cipher.key = @secret diff --git a/activerecord/lib/active_record/encryption/contexts.rb b/activerecord/lib/active_record/encryption/contexts.rb index e3ca491cf5..fe695d7fd5 100644 --- a/activerecord/lib/active_record/encryption/contexts.rb +++ b/activerecord/lib/active_record/encryption/contexts.rb @@ -19,7 +19,7 @@ module ActiveRecord end class_methods do - # Configures a custom encryption context to use when running the provided block of code + # Configures a custom encryption context to use when running the provided block of code. # # It supports overriding all the properties defined in +Context+. # diff --git a/activerecord/lib/active_record/encryption/derived_secret_key_provider.rb b/activerecord/lib/active_record/encryption/derived_secret_key_provider.rb index 6ec9e6604b..e12ece2b73 100644 --- a/activerecord/lib/active_record/encryption/derived_secret_key_provider.rb +++ b/activerecord/lib/active_record/encryption/derived_secret_key_provider.rb @@ -2,7 +2,7 @@ module ActiveRecord module Encryption - # A +KeyProvider+ that derives keys from passwords + # A +KeyProvider+ that derives keys from passwords. class DerivedSecretKeyProvider < KeyProvider def initialize(passwords) super(Array(passwords).collect { |password| Key.derive_from(password) }) diff --git a/activerecord/lib/active_record/encryption/encryptable_record.rb b/activerecord/lib/active_record/encryption/encryptable_record.rb index 80a8e6e414..e05214e2c5 100644 --- a/activerecord/lib/active_record/encryption/encryptable_record.rb +++ b/activerecord/lib/active_record/encryption/encryptable_record.rb @@ -57,7 +57,7 @@ module ActiveRecord end end - # Given a attribute name, it returns the name of the source attribute when it's a preserved one + # Given a attribute name, it returns the name of the source attribute when it's a preserved one. def source_attribute_from_preserved_attribute(attribute_name) attribute_name.to_s.sub(ORIGINAL_ATTRIBUTE_PREFIX, "") if /^#{ORIGINAL_ATTRIBUTE_PREFIX}/.match?(attribute_name) end @@ -133,17 +133,17 @@ module ActiveRecord end end - # Returns whether a given attribute is encrypted or not + # Returns whether a given attribute is encrypted or not. def encrypted_attribute?(attribute_name) ActiveRecord::Encryption.encryptor.encrypted? ciphertext_for(attribute_name) end - # Returns the ciphertext for +attribute_name+ + # Returns the ciphertext for +attribute_name+. def ciphertext_for(attribute_name) read_attribute_before_type_cast(attribute_name) end - # Encrypts all the encryptable attributes and saves the model + # Encrypts all the encryptable attributes and saves the model. # # === Options # @@ -159,7 +159,7 @@ module ActiveRecord end end - # Decrypts all the encryptable attributes and saves the model + # Decrypts all the encryptable attributes and saves the model. def decrypt transaction do decrypt_attributes if has_encrypted_attributes? diff --git a/activerecord/lib/active_record/encryption/encrypted_attribute_type.rb b/activerecord/lib/active_record/encryption/encrypted_attribute_type.rb index 42043c64d4..056eb8c6af 100644 --- a/activerecord/lib/active_record/encryption/encrypted_attribute_type.rb +++ b/activerecord/lib/active_record/encryption/encrypted_attribute_type.rb @@ -2,7 +2,7 @@ module ActiveRecord module Encryption - # An +ActiveModel::Type+ that encrypts/decrypts strings of text + # An +ActiveModel::Type+ that encrypts/decrypts strings of text. # # This is the central piece that connects the encryption system with +encrypts+ declarations in the # model classes. Whenever you declare an attribute as encrypted, it configures an +EncryptedAttributeType+ diff --git a/activerecord/lib/active_record/encryption/encrypted_fixtures.rb b/activerecord/lib/active_record/encryption/encrypted_fixtures.rb index f7f871e67a..a64dd42754 100644 --- a/activerecord/lib/active_record/encryption/encrypted_fixtures.rb +++ b/activerecord/lib/active_record/encryption/encrypted_fixtures.rb @@ -2,7 +2,6 @@ module ActiveRecord module Encryption - # Encrypts encryptable columns when loading fixtures automatically module EncryptedFixtures def initialize(fixture, model_class) @clean_values = {} diff --git a/activerecord/lib/active_record/encryption/encrypting_only_encryptor.rb b/activerecord/lib/active_record/encryption/encrypting_only_encryptor.rb index 90c0d37410..dc0c53a48d 100644 --- a/activerecord/lib/active_record/encryption/encrypting_only_encryptor.rb +++ b/activerecord/lib/active_record/encryption/encrypting_only_encryptor.rb @@ -2,7 +2,7 @@ module ActiveRecord module Encryption - # An encryptor that can encrypt data but can't decrypt it + # An encryptor that can encrypt data but can't decrypt it. class EncryptingOnlyEncryptor < Encryptor def decrypt(encrypted_text, key_provider: nil, cipher_options: {}) encrypted_text