如何使用TripleDES加密与Node.js和PHP-mcrypt获得相同的结果?

时间:2015-05-02 08:38:19

标签: php node.js encryption openssl mcrypt

这是使用本地Node.js中的crypto(基于OpenSSL)的3DES。

var secretKey         = "efd77bed61e8fdd0437df1ac";
var enchding          = 'hex';
var text              = 'This is test.';
var cipher            = modules.crypto.createCipher('des-ede3-cbc', secretKey);
var cryptedPassword   = cipher.update(text, 'utf8', enchding) + cipher.final(enchding);
  

输出为:af4ee52e0227fe40ab2e7ddd72fb1137

但是我使用了在线PHP-mcrypt加密工具(link here)。

键是efd77bed61e8fdd0437df1ac

算法为Tripledes,模式为CBC,并使用Hexa输出。

  

输出为:d4b374b7ac8df7883ab1d58c7db0b0cc

为什么这两种结果都不同?

如何在Node.js中使用crypto获得相同的结果?

1 个答案:

答案 0 :(得分:3)

您的代码存在多个问题。

  • crypto.createCipher(algorithm, password)使用密码而非密钥。实际密钥将从该密码派生。您似乎想要使用密钥而不是密码,因此您需要使用crypto.createCipheriv(algorithm, key, iv)

  • PHP的mcrypt模块仅应用零填充,但node.js的加密模块仅应用PKCS#5 / PKCS#7填充。您应该在PHP中使用PKCS#7填充,如显示here。 (在示例代码中使用)

  • 您必须在node.js和PHP中使用相同的IV。通常生成随机IV并将其预先附加到密文。在解密期间,必须将其切掉并使用。 (未包含在示例代码中)

<强>的node.js

var crypto = require('crypto');

var secretKey         = new Buffer("efd77bed61e8fdd0437df1ac", "utf8");
var iv                = new Buffer("\0\0\0\0\0\0\0\0");
var enchding          = 'hex';
var text              = 'This is test.';
var cipher            = crypto.createCipheriv('des-ede3-cbc', secretKey, iv);
var cryptedPassword   = cipher.update(text, 'utf8', enchding) + cipher.final(enchding);

console.log(cryptedPassword);

输出:

4e91635045f42185831403057ef16749

<强> PHP

function pkcs7pad($plaintext, $blocksize)
{
    $padsize = $blocksize - (strlen($plaintext) % $blocksize);
    return $plaintext . str_repeat(chr($padsize), $padsize);
}

$pt = pkcs7pad('This is test.', 8);
$iv = '\0\0\0\0\0\0\0\0';
$key = 'efd77bed61e8fdd0437df1ac';

$ct = mcrypt_encrypt(MCRYPT_3DES, $key, $pt, MCRYPT_MODE_CBC, $iv);

echo bin2hex($ct);

输出:

4e91635045f42185831403057ef16749

似乎您想加密密码。密码永远不应加密。使用像PBKDF2,bcrypt或scrypt这样的良好散列解决方案,并通过再次散列来验证密码。