我是否可以复制PHP';ruby中的AES加密?
我正在用RubyonRails重建一个PHP web应用程序,我非常希望避免强迫所有现有用户重置加密密码。PHP站点使用AES-256-ECB,而我一生都无法使用ruby获得相同的密码文本。我也不能解密它们(这在原则上是好的),因为用户数据库中实际存储的是AES密码文本的MD5散列 我已经阅读了前面这些密切相关的问题和非常有用的答案:我是否可以复制PHP';ruby中的AES加密?,php,ruby,encryption,aes,Php,Ruby,Encryption,Aes,我正在用RubyonRails重建一个PHP web应用程序,我非常希望避免强迫所有现有用户重置加密密码。PHP站点使用AES-256-ECB,而我一生都无法使用ruby获得相同的密码文本。我也不能解密它们(这在原则上是好的),因为用户数据库中实际存储的是AES密码文本的MD5散列 我已经阅读了前面这些密切相关的问题和非常有用的答案: 包括这里引用的页面,如果我理解正确,PHP和ruby实现使用不同的填充方法。既然我不得不接受PHP端的工作方式,有没有办法在ruby/OpenSSL上强制
$salt = "12345678901234567890123456789012";
$plain = "password";
$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);
$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
$cipher = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $salt, $plain, MCRYPT_MODE_ECB, $iv);
echo md5($cipher);
输出:6337137fd88148250fd135a43dbeb84a
在ruby中:
require 'openssl'
salt = "12345678901234567890123456789012"
plain = "password";
c = OpenSSL::Cipher.new("AES-256-ECB")
c.encrypt
c.key = salt
cipher = c.update(plain)
cipher << c.final
puts Digest::MD5.hexdigest(cipher)
需要“openssl”
salt=“123456789012134567890123456789012”
plain=“密码”;
c=OpenSSL::Cipher.new(“AES-256-ECB”)
c、 加密
c、 钥匙=盐
密码=c.update(普通)
cipher实际上通常不是一个openssl解决方案,但是您可以使用一个工作示例
require 'mcrypt'
require 'openssl'
plaintext = 'password'
puts plaintext
key = '12345678901234567890123456789012'
enc = Mcrypt.new(:rijndael_256, :ecb, key, nil, :zeros)
encrypted = enc.encrypt(plaintext)
puts Digest::MD5.hexdigest(encrypted)
我使用了一个额外的gem(ruby-mcrypt)。这似乎是openssl的一个问题。实际上,问题似乎是Openssl不支持零填充,并且使用无填充或默认Openssl填充。由于在php中使用零填充,所以在ruby中也必须使用零填充
php脚本在我的计算机上的输出:
[~/test] ➔ php5 t.php
6337137fd88148250fd135a43dbeb84a
对于ruby脚本:
[~/test] ➔ ruby t2.rb
password
6337137fd88148250fd135a43dbeb84a
以及我的ruby版本:
[~/test] ➔ ruby -version
ruby 1.9.2p0 (2010-08-18 revision 29036) [i686-linux]
希望这有帮助。如果您可以使用其他加密方法,您可以尝试茶块加密。我已经在Ruby、JS和ActionScript中采用了这种方法。它也应该与PHP一起工作。github repo是如果php端的键大小不是标准的,则需要用零填充键,直到下一个有效的键大小,以便使ruby端像这样工作:
php_encrypted = string_encoded_with_php_mcrypt
key = "longerthan16butnot24".to_a.pack('a24')
enc = Mcrypt.new(:rijndael_256, :ecb, key, nil, :zeros)
enc.decrypt(php_encrypted)
在这种情况下,下一个有效密钥长度是24
对于:rijndael_256,有效密钥长度为:16、24、32
您可以获得有关算法的更多信息:
Mcrypt.algorithm_info(:rijndael_256
我想说,您的ruby版本不包括随机生成的IV.AFAIK,您不需要显式分配它。在任何情况下,这样做都不会影响ruby的结果。@Kerrek:btw mcrypt中的ecb模式根本不使用IV。嘿,你的“盐”是不同的!是的,在他的例子中它们是不同的,但是即使他在ruby脚本中使用了正确的“密钥”,openssl也会输出一些不同的东西,因为我的文章中描述了填充。这就做到了,非常感谢。OpenSSL对我来说不是必需的,它只是一种ruby默认值。在安装了libmcrypt和ruby-mcrypt-gem之后,这一切都很好。谢谢,但是我需要在ruby中复制一个现有的PHP加密。fyr的回答成功了。