Enu*_*uff 2 javascript php encryption aes
我正在尝试使用JavaScript复制PHP字符串加密.这是PHP代码:
<?php
$iv = "1234567890123456";
$key = "aaaaaaaaaaaaaaaa";
$input = "texttexttexttext";
$encrypted = openssl_encrypt($input, "AES-256-CBC", $key, 0, $iv);
echo $encrypted;
// "ZwY1i+vqP3acszeDiscCTx/R4a6d2AtkcInmN9OTCNE="
Run Code Online (Sandbox Code Playgroud)
但是,当我尝试在JavaScript中复制它时,它会提供不同的密文:
var aesjs = require("aes-js");
var base64 = require("js-base64");
var iv = aesjs.utils.utf8.toBytes("1234567890123456");
var key = aesjs.utils.utf8.toBytes("aaaaaaaaaaaaaaaa");
var text = aesjs.utils.utf8.toBytes("texttexttexttext");
var aesCbc = new aesjs.ModeOfOperation.cbc(key, iv);
var encryptedBytes = aesCbc.encrypt(text);
var b64encoded = base64.Base64.encode(encryptedBytes);
console.log(b64encoded);
// "MTcyLDIsNjAsMTU5LDcxLDEwLDE4Myw4LDE…wyMTIsMjIyLDk3LDEyNCw1MywxNzIsMjIy"
Run Code Online (Sandbox Code Playgroud)
我不知道如何让它给出相同的输出.有任何想法吗?
有些事情出错了:
首先,JavaScript代码的输出实际上是字符串的base64编码172,2,60,159,71,10,183,8,1,…,而不是原始字节缓冲区的编码.我不知道如何解决这个问题,但通过使用aes.js十六进制编码实用程序函数,我们可以将其转换为base64:
var hex = aesjs.utils.hex.fromBytes(encryptedBytes);
var buf = Buffer.from(hex, 'hex');
console.log(buf.toString('base64'));
// rAI8n0cKtwiu1N5hfDWs3g==
Run Code Online (Sandbox Code Playgroud)
的第二问题是,在aes.js使用的是AES128加密(aaaaaaaaaaaaaaaa是128位长),但使用的是AES256加密在PHP代码.我们应该更新PHP代码(或JS代码):
$encrypted = openssl_encrypt($input, "AES-128-CBC", $key, 0, $iv);
echo $encrypted;
// rAI8n0cKtwiu1N5hfDWs3rPbz0UmvlbW+LJliYox03c=
Run Code Online (Sandbox Code Playgroud)
我们几乎有相同的输出.但是等等,PHP输出是两倍长.发生了什么?
好吧,OpenSSL 使用PKCS#7填充.但是,Javascript代码是未填充的.要解决此问题,您应该使用PKCS#7填充作为javascript文本.为此,您只需使用pkcs7模块即可.另一种选择是在计数器(CTR)模式下使用AES而不是CBC模式,如果这是您的选项.
这是我最后的PHP代码:
<?php
$iv = "1234567890123456";
$key = "aaaaaaaaaaaaaaaa";
$input = "texttexttexttext";
$encrypted = openssl_encrypt($input, "AES-128-CBC", $key, 0, $iv);
echo $encrypted;
// output: 'rAI8n0cKtwiu1N5hfDWs3rPbz0UmvlbW+LJliYox03c='
Run Code Online (Sandbox Code Playgroud)
这是JavaScript代码:
var aesjs = require("aes-js");
var base64 = require("js-base64");
var pkcs7 = require("pkcs7");
var iv = aesjs.utils.utf8.toBytes("1234567890123456");
var key = aesjs.utils.utf8.toBytes("aaaaaaaaaaaaaaaa");
var text = aesjs.utils.utf8.toBytes("texttexttexttext");
var aesCbc = new aesjs.ModeOfOperation.cbc(key, iv);
var encryptedBytes = aesCbc.encrypt(pkcs7.pad(text));
var hex = aesjs.utils.hex.fromBytes(encryptedBytes);
var buf = Buffer.from(hex, 'hex');
console.log(buf.toString('base64'));
// output: 'rAI8n0cKtwiu1N5hfDWs3rPbz0UmvlbW+LJliYox03c='
Run Code Online (Sandbox Code Playgroud)
PS我个人更喜欢使用CTR模式,因为PKCS#7实现有时会暴露破坏加密的填充特征.(我检查了提到的pkcs#7库应该是好的,但请不要尝试自己实现.)
| 归档时间: |
|
| 查看次数: |
357 次 |
| 最近记录: |