如果im在jruby而不是ruby中,为什么我的加密模块会返回不同的值

如果im在jruby而不是ruby中,为什么我的加密模块会返回不同的值,ruby,encryption,openssl,aes,jruby,Ruby,Encryption,Openssl,Aes,Jruby,我编写了一个非常基本的加密模块,用于加密.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(encrypt

我编写了一个非常基本的加密模块,用于加密.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==
我对加密比较陌生,所以这可能是一个加载或简单的问题,但为什么我的模块根据我使用的解释器返回两个不同的值

编辑:键是32字节,我已经将IV改为16字节,结果在口译员之间仍然不同

示例键:

key = 1DR337Z5C5CBD94643L9772F96C546AC  
iv  = 2BR367Z5R5CFD949

提供键和IV的全长值

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

在IV的情况下,长度需要是AES 16字节的块大小


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

使用OpenSSL,调用cipher.encrypt时,重置密钥和iv,或者至少以某种方式更改密码对象的内部状态。这方面存在一个Ruby bug:

似乎没有这种行为,无论您在哪里调用cipher.encrypt,都会给出相同的结果

解决方法/修复方法是确保在设置密钥和iv之前调用cipher.encrypt:

cipher.encrypt
cipher.key = ENV['KEY']
cipher.iv = ENV['IV']

我们没有实际值,他是从ENV hashyep获取的,我可以确认键和iv的长度完全相同。键和iv的长度不应该相同,因为您使用的是32字节的键。@Artjom键是32字节,iv是16字节-bytes@zaph只是试着把iv改成16个字节,还是一样。@zaph只是把它们添加到了问题中,每个问题中的输入填充是如何处理的?当我使用上面的输入键=1DR337Z5C5CBD94643L9772F96C546AC,iv=2BR367Z5R5CFD94:带有PKCS7填充的数据密码时,我得到:4cP7jptj5Z14c2KoXdNf+g==。@zaph,当我使用jruby 9.0.5.0.0-4CP7JPT5Z14COXDNFNF+g==,我得到了smae,然后,如果我用ruby 2.2.0运行它,我会得到y5zddfagrammk1wqy2e4eoia==@zaph好点,更新了问题。此外,我还将了解该库在指定填充方面提供了什么。