在Node.js中AES加密在PHP中解密。失败。 [英] AES encrypt in Node.js Decrypt in PHP. Fail.
问题描述
在node.js中,我使用build函数来加密这样的数据:
var text =Yes ;
var password =123456;
var encrypt = crypto.createCipher('aes-256-cbc',password);
var encryptOutput1 = encrypt.update(text,'base64','base64');
var encryptOutput2 = encrypt.final('base64');
var encryptedText = encryptOutput1 + encryptOutput2;
输出(加密文本)是:OnNINwXf6U8XmlgKJj48iA ==
然后我在PHP中使用解密:
$ encrypted ='OnNINwXf6U8XmlgKJj48iA ==';
(或$ encrypted = base64_decode('OnNINwXf6U8XmlgKJj48iA =='));
$ dtext2 = mcrypt_decrypt(MCRYPT_RIJNDAEL_256,$ key,$ encrypted,MCRYPT_MODE_CBC);
echoDecrypted:$ dtext2;
我会得到一些有趣的字符,我无法解密它。我尝试使用/没有base64_decode或MCRYPT_RIJNDAEL_128 ..都失败。
然后我检查了PHP中的加密,它看起来与node.js.的输出有很大的不同
$ text =是;
$ key =123456;
$ eText = mcrypt_encrypt(MCRYPT_RIJNDAEL_256,$ key,$ text,MCRYPT_MODE_CBC);
echo加密:$ eText \\\
;
echobase64:。 base64_encode($ eText)。 \\\
;
$ dtext1 = mcrypt_decrypt(MCRYPT_RIJNDAEL_256,$ key,$ eText,MCRYPT_MODE_CBC);
echoDecrypted:$ dtext1 \\\
\\\
;
它可以加密和解密。并且加密的数据是:njCE / fk3pLD1 / JfiQuyVa6w5H + Qb / utBIT3m7LAcetM =
这与node.js的输出有很大不同,请指教我如何加密和解密在node.js& PHP。谢谢。 :)
@Mel这里是我在PHP中的:
$ text =是;
$ key =32BytesLongKey560123456789ABCDEF;
$ iv =sixteenbyteslong;
/ *打开密码* /
$ td = mcrypt_module_open(MCRYPT_RIJNDAEL_128,'',MCRYPT_MODE_CBC,'');
/ *初始化加密* /
mcrypt_generic_init($ td,$ key,$ iv);
/ *加密数据* /
$ eText = mcrypt_generic($ td,$ text);
echo加密数据:$ eText \\\
;
echobase64:。 base64_encode($ eText)。 \\\
;
/ *终止加密处理程序* /
mcrypt_generic_deinit($ td);
/ *初始化加密模块进行解密* /
mcrypt_generic_init($ td,$ key,$ iv);
/ *解密加密的字符串* /
$ dText = mdecrypt_generic($ td,$ eText);
/ *终止解密句柄和关闭模块* /
mcrypt_generic_deinit($ td);
mcrypt_module_close($ td);
/ *显示字符串* /
echo trim($ dText)。 \\\
;
然而,它仍然不起作用。
PHP中加密的基础64是: 80022AGM4 / 4qQtiGU5oJDQ ==
nodejs中加密的基数64是: EoYRm5SCK7EPe847CwkffQ ==
因此,我无法解密PHP中的nodejs一个。
我想知道是不是因为nodejs不需要$ iv?
七个月后,但我也在努力,并找到了一个解决方案。显然,PHP使用零字节填充输入,使其大小成为块大小的倍数。例如,使用AES-128,14字节输入违禁者将用两个零字节填充,如下所示:
contrabassists\0\0
AN *块大小字节输入被留下。
然而,标准节点加密功能使用不同的填充方案PKCS5。 PKCS5不添加零,但是增加了填充的长度,所以再次使用AES-128,违反者将成为:
contrabassists\2\2
即使一个N *块大小的字节输入被填充PKCS5。否则,解码后无法删除填充。输入的谱图将变为:
spectroheliogram\16\16\16\16\16 \16\16\16\16\16\16\16\16\16\16\16
要使PHP m_crypt加密与Node解密兼容,您必须自己填写输入:
$ pad = $ blocksize - (strlen($ input)%$ blocksize);
$ input = $ input。 str_repeat(chr($ pad),$ pad);
相反,你必须读取解码数据的最后一个字节并切断
示例功能:(添加01-14-2012)
在PHP中,此函数将返回AES-128加密的十六进制编码数据,可以由Node解密:
function nodeEncrypt ($ data,$ key,$ iv){
$ blocksize = 16; // AES-128
$ pad = $ blocksize - (strlen($ data)%$ blocksize);
$ data = $ data。 str_repeat(chr($ pad),$ pad);
return bin2hex(mcrypt_encrypt(MCRYPT_RIJNDAEL_128,$ key,$ data,MCRYPT_MODE_CBC,$ iv));
}
在Node中,以下将解密数据:
function nodeDecrypt(data,key,iv){
var decipher = crypto.createDecipheriv('aes-128-cbc',key,iv );
var chunks = []
chunks.push(decipher.update(data.toString(),'hex','binary'))
chunks.push(decipher.final('binary '))
return chunks.join('')
}
没有做相反的事情,但是一旦了解填充方案,它应该是直接的。我没有对关键/ iv生成做任何假设。
In node.js, I use the build in function to encrypt data like that:
var text = "Yes";
var password = "123456";
var encrypt = crypto.createCipher('aes-256-cbc', password);
var encryptOutput1 = encrypt.update(text, 'base64', 'base64');
var encryptOutput2 = encrypt.final('base64');
var encryptedText = encryptOutput1 + encryptOutput2;
the output (encrypted text) is: OnNINwXf6U8XmlgKJj48iA==
Then I use decrypt it in PHP:
$encrypted = 'OnNINwXf6U8XmlgKJj48iA==';
(or $encrypted = base64_decode('OnNINwXf6U8XmlgKJj48iA==') );
$dtext2 = mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $key, $encrypted, MCRYPT_MODE_CBC);
echo "Decrypted: $dtext2";
I will get some funny characters, which I can't decrypted it. I tried with/without base64_decode or MCRYPT_RIJNDAEL_128.. all fail.
Then I check how the encryption in PHP, it looks very different from the output from node.js.
$text = "Yes";
$key = "123456";
$eText = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, $text, MCRYPT_MODE_CBC);
echo "Encrypted: $eText \n";
echo "base64: " . base64_encode($eText) . " \n";
$dtext1 = mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $key, $eText, MCRYPT_MODE_CBC);
echo "Decrypted: $dtext1 \n\n";
It can encrypt and decrypt. and the encrypted data is : njCE/fk3pLD1/JfiQuyVa6w5H+Qb/utBIT3m7LAcetM=
which is very different from the output from node.js please advise how I can encrypt and decrypt between node.js & php. thanks. :)
@Mel here is what I have in PHP:
$text = "Yes";
$key = "32BytesLongKey560123456789ABCDEF";
$iv = "sixteenbyteslong";
/* Open the cipher */
$td = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_CBC, '');
/* Intialize encryption */
mcrypt_generic_init($td, $key, $iv);
/* Encrypt data */
$eText = mcrypt_generic($td, $text);
echo "Encrypted Data: $eText \n";
echo "base64: " . base64_encode($eText) . " \n";
/* Terminate encryption handler */
mcrypt_generic_deinit($td);
/* Initialize encryption module for decryption */
mcrypt_generic_init($td, $key, $iv);
/* Decrypt encrypted string */
$dText = mdecrypt_generic($td, $eText);
/* Terminate decryption handle and close module */
mcrypt_generic_deinit($td);
mcrypt_module_close($td);
/* Show string */
echo trim($dText) . "\n";
However, it still doesn't work.
The encrypted base 64 in PHP is: 80022AGM4/4qQtiGU5oJDQ== The encrypted base 64 in nodejs is: EoYRm5SCK7EPe847CwkffQ==
thus, i can't decrypt the nodejs one in PHP.
I wonder if it is because nodejs doesn't require $iv?
Seven months late, but I was struggling with this as well, and found a solution. Apparently, PHP pads the input with zero bytes to make its size a multiple of the block size. For example, using AES-128, the 14 byte input "contrabassists" will be padded with two zero bytes, like this:
"contrabassists\0\0"
A N*blocksize byte input is left alone.
The standard Node crypto functions, however, use a different padding scheme called PKCS5. PKCS5 doesn't add zeros, but adds the length of the padding, so again using AES-128, "contrabassists" would become:
"contrabassists\2\2"
Even a N*blocksize byte input gets padded in PKCS5. Otherwise, it's impossible to remove the padding after decoding. The input "spectroheliogram" would then become:
"spectroheliogram\16\16\16\16\16\16\16\16\16\16\16\16\16\16\16\16"
To make PHP m_crypt encryption compatible with Node decryption, you'll have to pad the input yourself:
$pad = $blocksize - (strlen($input) % $blocksize);
$input = $input . str_repeat(chr($pad), $pad);
The other way around, you'll have to read the last byte of the decoded data and cut off the padding yourself.
Example functions: (added 01-14-2012)
In PHP, this function would return AES-128 encrypted, hex encoded data that can be decrypted by Node:
function nodeEncrypt($data, $key, $iv) {
$blocksize = 16; // AES-128
$pad = $blocksize - (strlen($data) % $blocksize);
$data = $data . str_repeat(chr($pad), $pad);
return bin2hex(mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $data, MCRYPT_MODE_CBC, $iv));
}
In Node, the following would decrypt the data:
function nodeDecrypt(data, key, iv) {
var decipher = crypto.createDecipheriv('aes-128-cbc', key, iv);
var chunks = []
chunks.push(decipher.update(data.toString(),'hex','binary'))
chunks.push(decipher.final('binary'))
return chunks.join('')
}
I haven't done the reverse yet, but it should be straightforward once you understand the padding scheme. I haven't made any assumptions about key/iv generation.
这篇关于在Node.js中AES加密在PHP中解密。失败。的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!