找到你要的答案

Q:How to get the same result with Node.js and PHP-mcrypt using TripleDES encryption?

Q:如何与Node.js和PHP使用TripleDES加密mcrypt得到同样的结果吗?

This is 3DES using crypto (base on OpenSSL) in native Node.js.

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);

output is : af4ee52e0227fe40ab2e7ddd72fb1137


But I used online PHP-mcrypt encrypt tool (link here).

Key is efd77bed61e8fdd0437df1ac

Algorithm is Tripledes, mode is CBC and output using Hexa.

output is : d4b374b7ac8df7883ab1d58c7db0b0cc


Why does both of these are different results?

And how can I get the same result using crypto in Node.js?

这是3des使用加密(基于OpenSSL)原生js。

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加密工具(链接)。

关键是efd77bed61e8fdd0437df1ac

算法TripleDES,模式CBC和输出使用六。

输出:d4b374b7ac8df7883ab1d58c7db0b0cc


为什么两者都是不同的结果?

我如何使用密码在Node.js得到同样的结果吗?

answer1: 回答1:

There are multiple issues with your code.

  • crypto.createCipher(algorithm, password) uses a password not a key. The actual key will be derived from that password. It seems that you want to use a key instead of a password, so you need to use crypto.createCipheriv(algorithm, key, iv).

  • PHP's mcrypt module only applies zero padding, but node.js' crypto module only applies PKCS#5/PKCS#7 padding. You should use PKCS#7 padding in PHP like shown here. (used in the example code)

  • You have to use the same IV in both node.js and PHP. Usually a random IV is generated and prepended to the ciphertext. During decryption it must be sliced off and used. (not included in the example code)

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);

output:

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);

output:

4e91635045f42185831403057ef16749

It seems you want to encrypt passwords. Passwords should never be encrypted. Use a good hashing solution like PBKDF2, bcrypt or scrypt and verify the password by hashing it again.

有多个问题与您的代码。

  • 密码。createcipher(算法,密码)使用一个密码不是关键。实际密钥将来自该密码。看来你想用来代替密码的关键,所以你需要使用密码。createcipheriv(算法、密钥、IV)。

  • PHP的mcrypt模块只适用于零填充,但节点。JS的密码模块只适用于# PKCS 5 / 7和#填充。你应该使用PKCS 7 PHP #填充如图所示。(在示例代码中使用)

  • 你必须在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核实一遍密码散列。

php  node.js  encryption  openssl  mcrypt