如何使用TripleDES加密获得与Node.js和PHP-mcrypt相同的结果? [英] How to get the same result with Node.js and PHP-mcrypt using TripleDES encryption?

查看:774
本文介绍了如何使用TripleDES加密获得与Node.js和PHP-mcrypt相同的结果?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

  var secretKey =efd77bed61e8fdd0437df1ac; 
var enchding ='hex';
var text ='这是测试。
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 / p>

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


输出是:d4b374b7ac8df7883ab1d58c7db0b0cc







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



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

解决方案

p>您的代码有多个问题。




  • crypto.createCi pher(算法,密码) 使用密码不是密钥。实际的密钥将从该密码导出。您似乎要使用密钥而不是密码,因此您需要使用 crypto.createCipheriv(algorithm,key,iv)


  • PHP的mcrypt模块只适用于零填充,但是node.js的加密模块只能应用PKCS#5 / PKCS#7填充。您应该在PHP中使用PKCS#7填充,如此处。 (在示例代码中使用)


  • 您必须在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 ='这是测试。
var cipher = crypto.createCipheriv('des-ede3-cbc',secretKey,iv);
var cryptedPassword = cipher.update(text,'utf8',enchding)+ cipher.final(enchding);

console.log(cryptedPassword);

输出:

 code> 4e91635045f42185831403057ef16749 

PHP

 函数pkcs7pad($ plaintext,$ blocksize)
{
$ padsize = $ blocksize - (strlen ($ plaintext)%$ blocksize);
返回$明文。 str_repeat(chr($ padsize),$ padsize);
}

$ pt = pkcs7pad('这是测试',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);

输出:

 code> 4e91635045f42185831403057ef16749 






加密密码密码不应该被加密。使用一个很好的哈希解决方案,如PBKDF2,bcrypt或scrypt,并通过再次哈希验证密码。


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?

解决方案

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.

这篇关于如何使用TripleDES加密获得与Node.js和PHP-mcrypt相同的结果?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆