Node.js 中的 AES 加密 PHP 中的解密.失败.

AES encrypt in Node.js Decrypt in PHP. Fail. (Node.js 中的 AES 加密 PHP 中的解密.失败.)
本文介绍了Node.js 中的 AES 加密 PHP 中的解密.失败.的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

问题描述

在 node.js 中,我使用内置函数来加密数据:

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;

输出(加密文本)为:OnNINwXf6U8XmlgKJj48iA==

the output (encrypted text) is: OnNINwXf6U8XmlgKJj48iA==

然后我在 PHP 中使用解密:

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

我会得到一些我无法解密的有趣字符.我尝试使用/不使用 base64_decode 或 MCRYPT_RIJNDAEL_128 .. 都失败了.

I will get some funny characters, which I can't decrypted it. I tried with/without base64_decode or MCRYPT_RIJNDAEL_128.. all fail.

然后我检查了PHP中的加密方式,它看起来与node.js的输出非常不同.

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 
";
    echo "base64: " . base64_encode($eText) . " 
";

    $dtext1 = mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $key, $eText, MCRYPT_MODE_CBC);
    echo "Decrypted: $dtext1 

";

它可以加密和解密.加密数据为:njCE/fk3pLD1/JfiQuyVa6w5H+Qb/utBIT3m7LAcetM=

It can encrypt and decrypt. and the encrypted data is : njCE/fk3pLD1/JfiQuyVa6w5H+Qb/utBIT3m7LAcetM=

这与 node.js 的输出非常不同,请告知我如何在 node.js & 之间进行加密和解密.php.ini谢谢.:)

which is very different from the output from node.js please advise how I can encrypt and decrypt between node.js & php. thanks. :)

@Mel 这是我在 PHP 中所拥有的:

@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 
";
echo "base64: " . base64_encode($eText) . " 
";

/* 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) . "
";

然而,它仍然不起作用.

However, it still doesn't work.

PHP 中加密的 base 64 为:80022AGM4/4qQtiGU5oJDQ==nodejs中加密的base 64为:EoYRm5SCK7EPe847CwkffQ==

The encrypted base 64 in PHP is: 80022AGM4/4qQtiGU5oJDQ== The encrypted base 64 in nodejs is: EoYRm5SCK7EPe847CwkffQ==

因此,我无法在 PHP 中解密 nodejs 之一.

thus, i can't decrypt the nodejs one in PHP.

不知道是不是因为nodejs不需要$iv?

I wonder if it is because nodejs doesn't require $iv?

推荐答案

晚了七个月,但我也在为此苦苦挣扎,并找到了解决方案.显然,PHP 用零字节填充输入以使其大小成为块大小的倍数.例如,使用 AES-128,14 字节输入contrabassists"将填充两个零字节,如下所示:

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"

一个 N*blocksize 字节的输入被单独留下.

A N*blocksize byte input is left alone.

然而,标准的 Node 加密函数使用一种不同的填充方案,称为 PKCS5.PKCS5 不添加零,但会添加填充的长度,因此再次使用 AES-128,低音提琴手"将变为:

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:

"contrabassists22"

即使是 N*blocksize 字节输入也会在 PKCS5 中填充.否则,解码后无法去除填充.输入的光谱日光图"将变为:

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:

"spectroheliogram16161616161616161616161616161616"

要使 PHP m_crypt 加密与 Node 解密兼容,您必须自己填充输入:

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.

示例函数:(2012 年 1 月 14 日添加)

Example functions: (added 01-14-2012)

在 PHP 中,此函数将返回 AES-128 加密的十六进制编码数据,节点可以解密:

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

在 Node 中,以下将解密数据:

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('')
}

我还没有做过相反的事情,但是一旦你理解了填充方案,它应该很简单.我没有对 key/iv 生成做任何假设.

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 中的解密.失败.的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

本站部分内容来源互联网,如果有图片或者内容侵犯了您的权益,请联系我们,我们会在确认后第一时间进行删除!

相关文档推荐

DeepL的翻译效果还是很强大的,如果我们要用php实现DeepL翻译调用,该怎么办呢?以下是代码示例,希望能够帮到需要的朋友。 在这里需要注意,这个DeepL的账户和api申请比较难,不支持中国大陆申请,需要拥有香港或者海外信用卡才行,没账号的话,目前某宝可以
PHP通过phpspreadsheet导入Excel日期,导入系统后,全部变为了4开头的几位数字,这是为什么呢?原因很简单,将Excel的时间设置问文本,我们就能看到该日期本来的数值,上图对应的数值为: 要怎么解决呢?进行数据转换就行,这里可以封装方法,或者用第三方的
mediatemple - can#39;t send email using codeigniter(mediatemple - 无法使用 codeigniter 发送电子邮件)
Laravel Gmail Configuration Error(Laravel Gmail 配置错误)
Problem with using PHPMailer for SMTP(将 PHPMailer 用于 SMTP 的问题)
Issue on how to setup SMTP using PHPMailer in GoDaddy server(关于如何在 GoDaddy 服务器中使用 PHPMailer 设置 SMTP 的问题)