Decrypting Fields Encrypted by Rails Active Record Encryptor in Plain Ruby

142 views Asked by At

I have a Rails application with a table named "orders" containing encrypted fields. The encryption is handled by Rails 7's built-in Active Record Encryption feature.

I'm attempting to write a Ruby lambda function outside of the Rails application to decrypt the encrypted data. I've ensured that I'm using the same encryption key as in my Rails app, but decryption is unsuccessful.

Could you help me troubleshoot and resolve this decryption issue?

I tried in plain ruby but my code is giving error. My code as follows

lambada_function.rb


require 'active_support/all'

require 'active_record'
require_relative 'application'
require_relative './models/order'
require 'pry'

last_order = Order.last

ActiveRecord::Encryption::Encryptor.new.decrypt(last_order.user_surname)

application.rb

# frozen_string_literal: true

require 'active_record'
require 'tzinfo'

class Application
  env_file = File.join('./config_env.yml')
  YAML.safe_load(File.open(env_file), aliases: true).each do |key, value|
    ENV[key.to_s] = value
  end

  db_configuration_file_path = './db/database.yml'
  db_configuration = YAML.safe_load(File.read(db_configuration_file_path), aliases: true)

  ActiveRecord::Base.establish_connection(db_configuration['production'])
  tz = TZInfo::Timezone.get('Asia/Tokyo')
  Time.zone = tz

  ActiveRecord.default_timezone = :local
  ActiveRecord::Encryption.configure(
    primary_key: ENV['PRIMARY_KEY'],
    deterministic_key: ENV['DETERMINISTIC_KEY'],
    key_derivation_salt: ENV['KEY_DERIVATION_SALT'],
    support_unencrypted_data: true
  )
end

order.rb

class Order < ActiveRecord::Base
  # encrypt user information
  encrypts :user_name, deterministic: true
end

Error:

/Users/vebuinuser/Documents/Belc/ruby_lambada/ruby/3.2.0/gems/activerecord-7.0.4/lib/active_record/encryption/encryptor.rb:58:in `rescue in decrypt': ActiveRecord::Encryption::Errors::Decryption (ActiveRecord::Encryption::Errors::Decryption)
    from /Users/vebuinuser/Documents/Belc/ruby_lambada/ruby/3.2.0/gems/activerecord-7.0.4/lib/active_record/encryption/encryptor.rb:52:in `decrypt'
    from lambda_function.rb:10:in `<main>'
/Users/vebuinuser/Documents/Belc/ruby_lambada/ruby/3.2.0/gems/activerecord-7.0.4/lib/active_record/encryption/cipher/aes256_gcm.rb:80:in `rescue in decrypt': ActiveRecord::Encryption::Errors::Decryption (ActiveRecord::Encryption::Errors::Decryption)
    from /Users/vebuinuser/Documents/Belc/ruby_lambada/ruby/3.2.0/gems/activerecord-7.0.4/lib/active_record/encryption/cipher/aes256_gcm.rb:56:in `decrypt'
    from /Users/vebuinuser/Documents/Belc/ruby_lambada/ruby/3.2.0/gems/activerecord-7.0.4/lib/active_record/encryption/cipher.rb:42:in `block in try_to_decrypt_with_each'
    from /Users/vebuinuser/Documents/Belc/ruby_lambada/ruby/3.2.0/gems/activerecord-7.0.4/lib/active_record/encryption/cipher.rb:41:in `each'
    from /Users/vebuinuser/Documents/Belc/ruby_lambada/ruby/3.2.0/gems/activerecord-7.0.4/lib/active_record/encryption/cipher.rb:41:in `with_index'
    from /Users/vebuinuser/Documents/Belc/ruby_lambada/ruby/3.2.0/gems/activerecord-7.0.4/lib/active_record/encryption/cipher.rb:41:in `try_to_decrypt_with_each'
    from /Users/vebuinuser/Documents/Belc/ruby_lambada/ruby/3.2.0/gems/activerecord-7.0.4/lib/active_record/encryption/cipher.rb:26:in `decrypt'
    from /Users/vebuinuser/Documents/Belc/ruby_lambada/ruby/3.2.0/gems/activerecord-7.0.4/lib/active_record/encryption/encryptor.rb:56:in `decrypt'
    from lambda_function.rb:10:in `<main>'
/Users/vebuinuser/Documents/Belc/ruby_lambada/ruby/3.2.0/gems/activerecord-7.0.4/lib/active_record/encryption/cipher/aes256_gcm.rb:76:in `final': OpenSSL::Cipher::CipherError
    from /Users/vebuinuser/Documents/Belc/ruby_lambada/ruby/3.2.0/gems/activerecord-7.0.4/lib/active_record/encryption/cipher/aes256_gcm.rb:76:in `decrypt'
    from /Users/vebuinuser/Documents/Belc/ruby_lambada/ruby/3.2.0/gems/activerecord-7.0.4/lib/active_record/encryption/cipher.rb:42:in `block in try_to_decrypt_with_each'
    from /Users/vebuinuser/Documents/Belc/ruby_lambada/ruby/3.2.0/gems/activerecord-7.0.4/lib/active_record/encryption/cipher.rb:41:in `each'
    from /Users/vebuinuser/Documents/Belc/ruby_lambada/ruby/3.2.0/gems/activerecord-7.0.4/lib/active_record/encryption/cipher.rb:41:in `with_index'
    from /Users/vebuinuser/Documents/Belc/ruby_lambada/ruby/3.2.0/gems/activerecord-7.0.4/lib/active_record/encryption/cipher.rb:41:in `try_to_decrypt_with_each'
    from /Users/vebuinuser/Documents/Belc/ruby_lambada/ruby/3.2.0/gems/activerecord-7.0.4/lib/active_record/encryption/cipher.rb:26:in `decrypt'
    from /Users/vebuinuser/Documents/Belc/ruby_lambada/ruby/3.2.0/gems/activerecord-7.0.4/lib/active_record/encryption/encryptor.rb:56:in `decrypt'
    from lambda_function.rb:10:in `<main>'
1

There are 1 answers

1
dpaluy On

I had a similar issue when I migrated to Rails 7.1 The root cause was different hash algorithm usage SHA1 vs SHA256.

The solution is:

  1. Add the following to your application.rb: config.active_record.encryption.support_sha1_for_non_deterministic_encryption = true

  2. Re-encrypt the data

Reference: https://github.com/rails/rails/issues/48204#issuecomment-1760022815