Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
我是否可以复制PHP';ruby中的AES加密?_Php_Ruby_Encryption_Aes - Fatal编程技术网

我是否可以复制PHP';ruby中的AES加密?

我是否可以复制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上强制

我正在用RubyonRails重建一个PHP web应用程序,我非常希望避免强迫所有现有用户重置加密密码。PHP站点使用AES-256-ECB,而我一生都无法使用ruby获得相同的密码文本。我也不能解密它们(这在原则上是好的),因为用户数据库中实际存储的是AES密码文本的MD5散列

我已经阅读了前面这些密切相关的问题和非常有用的答案:

包括这里引用的页面,如果我理解正确,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

在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的回答成功了。