Sha256: 1d470c3c09f6834b1e34084b56eaed0afff3cb19aef5957ff27102831925cc38

Contents?: true

Size: 1.77 KB

Versions: 85

Compression:

Stored size: 1.77 KB

Contents

# frozen_string_literal: true

module ActiveRecord
  module Encryption
    # The algorithm used for encrypting and decrypting +Message+ objects.
    #
    # 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+.
    class Cipher
      DEFAULT_ENCODING = Encoding::UTF_8

      # 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+.
      #
      # When +key+ is an Array, it will try all the keys raising a
      # +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)
        end
      end

      def key_length
        Aes256Gcm.key_length
      end

      def iv_length
        Aes256Gcm.iv_length
      end

      private
        def try_to_decrypt_with_each(encrypted_text, keys:)
          keys.each.with_index do |key, index|
            return cipher_for(key).decrypt(encrypted_text)
          rescue ActiveRecord::Encryption::Errors::Decryption
            raise if index == keys.length - 1
          end
        end

        def cipher_for(secret, deterministic: false)
          Aes256Gcm.new(secret, deterministic: deterministic)
        end
    end
  end
end

Version data entries

85 entries across 82 versions & 9 rubygems

Version Path
activerecord-8.0.2 lib/active_record/encryption/cipher.rb
trusty-cms-7.0.9.1 vendor/bundle/ruby/3.3.0/gems/activerecord-7.0.8.7/lib/active_record/encryption/cipher.rb
minato_ruby_api_client-0.2.2 vendor/bundle/ruby/3.2.0/gems/activerecord-7.1.3.4/lib/active_record/encryption/cipher.rb
activerecord-8.0.1 lib/active_record/encryption/cipher.rb
activerecord-8.0.0.1 lib/active_record/encryption/cipher.rb
activerecord-7.2.2.1 lib/active_record/encryption/cipher.rb
activerecord-7.1.5.1 lib/active_record/encryption/cipher.rb
activerecord-7.0.8.7 lib/active_record/encryption/cipher.rb
activerecord-8.0.0 lib/active_record/encryption/cipher.rb
activerecord-7.2.2 lib/active_record/encryption/cipher.rb
activerecord-7.1.5 lib/active_record/encryption/cipher.rb
activerecord-8.0.0.rc2 lib/active_record/encryption/cipher.rb
activerecord-7.2.1.2 lib/active_record/encryption/cipher.rb
activerecord-7.1.4.2 lib/active_record/encryption/cipher.rb
activerecord-7.0.8.6 lib/active_record/encryption/cipher.rb
activerecord-8.0.0.rc1 lib/active_record/encryption/cipher.rb
activerecord-7.2.1.1 lib/active_record/encryption/cipher.rb
activerecord-7.1.4.1 lib/active_record/encryption/cipher.rb
activerecord-7.0.8.5 lib/active_record/encryption/cipher.rb
activerecord-8.0.0.beta1 lib/active_record/encryption/cipher.rb