Ruby 3DES实现与PHP mcrypt相比,结果不同

时间:2015-11-13 12:56:27

标签: php ruby 3des

我尝试将一些旧版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;
}

这是我的红宝石代码:

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==

正如您所看到的那样,字符串字节的最低部分是不同的。任何指针都非常感激。

2 个答案:

答案 0 :(得分:3)

我回答我自己的问题。

这是关于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 += "\0" 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 += "\0" until json.bytesize % block_length == 0

这些是我原始实现中缺少的重要部分。

答案 1 :(得分:0)

PHPMCRYPT_3DES的{​​{1}}组合可能不等同于红宝石MCRYPT_MODE_CBCOpenSSL(或3des })。 There are examples of other mismatches

尝试其他一种模式,例如des-ede3-cbcdes-ede-cbc(参阅完整列表here