在纯 Ruby 中解密由 Rails Active Record Encryptor 加密的字段

问题描述 投票:0回答:1

我有一个 Rails 应用程序,其中有一个名为“orders”的表,其中包含加密字段。加密由 Rails 7 的内置 Active Record 加密功能处理。

我正在尝试在 Rails 应用程序外部编写 Ruby lambda 函数来解密加密数据。我已确保使用与 Rails 应用程序中相同的加密密钥,但解密不成功。

您能帮我排查并解决这个解密问题吗?

我尝试使用普通的 ruby,但我的代码出现错误。 我的代码如下

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)

应用程序.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

订单.rb

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

错误:

/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>'
ruby-on-rails encryption activerecord rails-activerecord
1个回答
0
投票

当我迁移到 Rails 7.1 时,我遇到了类似的问题 根本原因是 SHA1 与 SHA256 的哈希算法使用不同。

解决办法是:

  1. 将以下内容添加到您的

    application.rb
    config.active_record.encryption.support_sha1_for_non_deterministic_encryption = true

  2. 重新加密数据

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

© www.soinside.com 2019 - 2024. All rights reserved.