我正在使用Ruby on Rails重建PHP Web应用程序,并且非常希望避免强制所有现有用户重置其加密密码 . PHP站点使用mcrypt_encrypt和AES-256-ECB,我可以't for the life of me get the same cipher text using ruby' s OpenSSL . 我可以't decrypt them either (which is good in principle) since what'实际存储在用户DB中的是AES密文的MD5哈希值 .
我已经阅读了这些以前密切相关的问题以及非常有用的答案:
-
How to make Ruby AES-256-CBC and PHP MCRYPT_RIJNDAEL_128 play well together
-
Part II: How to make Ruby AES-256-CBC and PHP MCRYPT_RIJNDAEL_128 play well together
包括那里引用的页面,如果我理解正确,PHP和ruby实现使用不同的填充方法 . 既然我不得不接受PHP方面的工作方式,有没有办法在某种程度上强制使用ruby / OpenSSL上相同的填充方法?我正在使用ruby 1.9.2-p180 .
这是PHP中的示例代码:
$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
在红宝石中:
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)
输出: 18dee36145c07ab83452aefe2590c391
3 回答
实际上通常不是一个openssl解决方案,但也许你可以有一个有效的例子 .
我使用了额外的宝石(ruby-mcrypt) . 似乎是openssl的一个问题 . 实际上问题似乎是Openssl不支持零填充并使用no-padding或default-openssl-padding . 由于你在php中使用零填充这一事实你必须在ruby中使用零填充 .
在我的机器上输出php脚本:
并为ruby脚本:
和我的红宝石版本:
希望这可以帮助 .
如果密钥大小在php端不是标准的,你需要用零填充密钥到下一个有效的密钥大小,以使ruby端工作如下:
在这种情况下,下一个有效密钥长度为24 .
对于:rijndael_256有效密钥长度为:16,24,32
您可以获得有关算法的更多信息:
如果您可以使用其他加密方法,则可以尝试TEA块加密 . 我已经采用了Ruby,JS,ActionScript的方法 . 它也应该与PHP一起使用 . github repo是here