如果我在 jruby 而不是 ruby 中,为什么我的加密模块 return 有不同的值

Why does my encryption module return different values if im in jruby instead of ruby

我写了一个非常基本的加密模块,我用它来加密 .yaml 文件中的一些值。

require 'OpenSSL'
require 'Base64'

cipher = OpenSSL::Cipher::AES.new(256, :CBC)
cipher.key = ENV['KEY']
cipher.iv = ENV['IV']
cipher.encrypt
encrypted = cipher.update(ARGV[0]) + cipher.final
p Base64.encode64(encrypted).gsub!(/\n/,'')

如果我运行加密器这样,我得到一个值

rvm use jruby-9.0.5.0    
jruby encryptor.rb 'password'
4cP7jptj5Z14c2KoXdNf+g==

如果我 运行 这样的加密器,我会收到不同的值

rvm use ruby-2.2.0    
ruby encryptor.rb 'password'
y5ZdDfAGRmK1wQy2e4EOIA==

我对加密比较陌生,所以这可能是一个很复杂的(或简单的)问题,但为什么我的模块 return 有两个不同的值,具体取决于我使用的解释器?

编辑: 密钥是 32 字节,我已经将 IV 更改为 16 字节,结果在解释器之间仍然不同。

示例键:

key = 1DR337Z5C5CBD94643L9772F96C546AC  
iv  = 2BR367Z5R5CFD949

为密钥和 IV 提供全长值。

对于密钥,您需要 256 位(32 字节)。

在 IV 的情况下,长度需要是(对于 AES)16 字节的块大小。

如果输入太短,则没有关于如何处理此问题的标准,并且每个实现可能会选择不同的方法,例如空填充或仅使用紧跟在提供的值之后的任何字节。

使用 OpenSSL,当您调用 cipher.encrypt 时,您会重置密钥和 iv(或者至少以某种方式更改 cipher 对象的内部状态)。关于这个有一个 Ruby 错误:https://bugs.ruby-lang.org/issues/8720

JRuby OpenSSL emulation layer 似乎没有这种行为,无论你在哪里调用 cipher.encrypt.

都会得到相同的结果

解决方法/修复是确保在设置密钥和 iv:

之前调用cipher.encrypt
cipher.encrypt
cipher.key = ENV['KEY']
cipher.iv = ENV['IV']