1

一段时间以来,我一直在使用ActiveSupport::MessageEncryptor使用其默认的 AES-256-CBC 密码对某些用户数据进行加密。在看到Rails 问题 #28135 之后,我想转换为AES-128-GCM,就像Rails 为其机密功能所做的那样。我开始遇到异常,所以我基于MessageEncryptor 示例ActiveSupport::MessageEncryptor::InvalidMessage创建了一个简单的测试用例:

["aes-256-cbc", "aes-128-gcm"].each do |cipher|
  puts "Cipher: #{cipher}"
  salt  = SecureRandom.random_bytes(64)
  key   = ActiveSupport::KeyGenerator.new('password').generate_key(salt, 32)
  crypt = ActiveSupport::MessageEncryptor.new(key, cipher: cipher)
  encrypted_data = crypt.encrypt_and_sign('my secret data')
  puts crypt.decrypt_and_verify(encrypted_data)
end

输出:

Cipher: aes-256-cbc
my secret data
Cipher: aes-128-gcm
ActiveSupport::MessageEncryptor::InvalidMessage: ActiveSupport::MessageEncryptor::InvalidMessage
        from /home/kevin/.gem/ruby/gems/activesupport-5.0.2/lib/active_support/message_encryptor.rb:103:in `rescue in _decrypt'
        from /home/kevin/.gem/ruby/gems/activesupport-5.0.2/lib/active_support/message_encryptor.rb:91:in `_decrypt'
        from /home/kevin/.gem/ruby/gems/activesupport-5.0.2/lib/active_support/message_encryptor.rb:66:in `decrypt_and_verify'
        from /work/myplaceonline/src/src/myplaceonline_rails/app/lib/myp.rb:2287:in `block in play'
        from /work/myplaceonline/src/src/myplaceonline_rails/app/lib/myp.rb:2281:in `each'
        from /work/myplaceonline/src/src/myplaceonline_rails/app/lib/myp.rb:2281:in `play'
        from (irb):3
        from /home/kevin/.gem/ruby/gems/railties-5.0.2/lib/rails/commands/console.rb:65:in `start'
        from /home/kevin/.gem/ruby/gems/railties-5.0.2/lib/rails/commands/console_helper.rb:9:in `start'
        from /home/kevin/.gem/ruby/gems/railties-5.0.2/lib/rails/commands/commands_tasks.rb:78:in `console'
        from /home/kevin/.gem/ruby/gems/railties-5.0.2/lib/rails/commands/commands_tasks.rb:49:in `run_command!'
        from /home/kevin/.gem/ruby/gems/railties-5.0.2/lib/rails/commands.rb:18:in `<top (required)>'
        from bin/rails:4:in `require'
        from bin/rails:4:in `<main>'

我在 Fedora 25 64 位上使用带有 openssl-1.0.2k-1 的 Rails 5.0.2(上面引用的 Rails 拉取请求表明 openssl 1.0.1 应该支持 AES-128-GCM)。我的 openssl 密码列表似乎支持 GCM:

$ openssl ciphers
ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:ECDHE-ECDSA-DES-CBC3-SHA:AES256-GCM-SHA384:AES256-SHA256:AES256-SHA:CAMELLIA256-SHA:AES128-GCM-SHA256:AES128-SHA256:AES128-SHA:CAMELLIA128-SHA:DES-CBC3-SHA:DHE-DSS-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA256:DHE-RSA-AES256-SHA:DHE-DSS-AES256-SHA:DHE-RSA-CAMELLIA256-SHA:DHE-DSS-CAMELLIA256-SHA:DHE-DSS-AES128-GCM-SHA256:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES128-SHA256:DHE-DSS-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA:DHE-RSA-CAMELLIA128-SHA:DHE-DSS-CAMELLIA128-SHA:EDH-RSA-DES-CBC3-SHA:EDH-DSS-DES-CBC3-SHA:PSK-AES256-CBC-SHA:PSK-AES128-CBC-SHA:PSK-3DES-EDE-CBC-SHA

ruby 2.3.3p222(2016-11-21 修订版 56859)[x86_64-linux]

4

1 回答 1

1

您的示例中 generate_key 的第二个参数(key_size)对于 aes-256-cbc 必须是 32 字节,对于 aes-128-gcm 必须是 16 字节。

于 2018-09-22T05:45:38.270 回答