Ruby 3DES 实现与 PHP mcrypt,不同的结果
Ruby 3DES implementation vs PHP mcrypt, different results
我正在尝试将一些遗留 PHP 代码迁移到 ruby,但我遇到了一些 3DES 加密问题。这是使用 mcrypt:
的 PHP 实现
function encrypt_3DES($message, $key){
$bytes = array(0,0,0,0,0,0,0,0); //byte [] IV = {0, 0, 0, 0, 0, 0, 0, 0}
$iv = implode(array_map("chr", $bytes)); //PHP 4 >= 4.0.2
$ciphertext = mcrypt_encrypt(MCRYPT_3DES, $key, $message, MCRYPT_MODE_CBC, $iv);
return $ciphertext;
}
这是我的 ruby 代码:
def encrypt_3DES(message, key)
des=OpenSSL::Cipher.new('des3')
des.encrypt
des.key = key
des.update(message)+des.final
end
但是结果略有不同(base64 编码):
//PHP
ZpgH7NWpRx+Mi6tDBZ9q2Q==
# Ruby
ZpgH7NWpRx/usGDIsQ+A8A==
如您所见,不同的是字符串字节的最低部分。非常感谢任何指点。
MCRYPT_3DES
和 MCRYPT_MODE_CBC
的 PHP
组合是否不等同于 ruby OpenSSL
库的 3des
(或 des-ede3-cbc
). There are examples of other mismatches。
尝试其他模式之一,例如 des-ede-cbc
或 des-cbc
(查看完整列表 here)
我回答我自己的问题。
这是一个关于 openssl 和 mcrypt 实现如何使用填充的问题。我的密码学知识不太深,但我在这里找到了一个可用的代码示例 http://opensourcetester.co.uk/2012/11/29/zeros-padding-3des-ruby-openssl/
#ENCRYPTION
block_length = 8
des.padding = 0 #Tell Openssl not to pad
des.encrypt
json = '{"somekey":"somevalue"}'
json += "[=10=]" until json.bytesize % block_length == 0 #Pad with zeros
edata = des.update(json) + des.final
b64data = Base64.encode64(edata).gsub("\n",'')
基本上,ruby openssl 将使用 PKCS 填充,而 mcrypt 使用 0 填充。所以在我们的代码中,我不得不告诉 openssl 不要用 des.padding = 0
填充字符串,然后手动进行填充:json += "[=12=]" until json.bytesize % block_length == 0
。
这些是我最初实施中遗漏的重要部分。
我正在尝试将一些遗留 PHP 代码迁移到 ruby,但我遇到了一些 3DES 加密问题。这是使用 mcrypt:
的 PHP 实现function encrypt_3DES($message, $key){
$bytes = array(0,0,0,0,0,0,0,0); //byte [] IV = {0, 0, 0, 0, 0, 0, 0, 0}
$iv = implode(array_map("chr", $bytes)); //PHP 4 >= 4.0.2
$ciphertext = mcrypt_encrypt(MCRYPT_3DES, $key, $message, MCRYPT_MODE_CBC, $iv);
return $ciphertext;
}
这是我的 ruby 代码:
def encrypt_3DES(message, key)
des=OpenSSL::Cipher.new('des3')
des.encrypt
des.key = key
des.update(message)+des.final
end
但是结果略有不同(base64 编码):
//PHP
ZpgH7NWpRx+Mi6tDBZ9q2Q==
# Ruby
ZpgH7NWpRx/usGDIsQ+A8A==
如您所见,不同的是字符串字节的最低部分。非常感谢任何指点。
MCRYPT_3DES
和 MCRYPT_MODE_CBC
的 PHP
组合是否不等同于 ruby OpenSSL
库的 3des
(或 des-ede3-cbc
). There are examples of other mismatches。
尝试其他模式之一,例如 des-ede-cbc
或 des-cbc
(查看完整列表 here)
我回答我自己的问题。
这是一个关于 openssl 和 mcrypt 实现如何使用填充的问题。我的密码学知识不太深,但我在这里找到了一个可用的代码示例 http://opensourcetester.co.uk/2012/11/29/zeros-padding-3des-ruby-openssl/
#ENCRYPTION
block_length = 8
des.padding = 0 #Tell Openssl not to pad
des.encrypt
json = '{"somekey":"somevalue"}'
json += "[=10=]" until json.bytesize % block_length == 0 #Pad with zeros
edata = des.update(json) + des.final
b64data = Base64.encode64(edata).gsub("\n",'')
基本上,ruby openssl 将使用 PKCS 填充,而 mcrypt 使用 0 填充。所以在我们的代码中,我不得不告诉 openssl 不要用 des.padding = 0
填充字符串,然后手动进行填充:json += "[=12=]" until json.bytesize % block_length == 0
。
这些是我最初实施中遗漏的重要部分。