我有一个API,要求我对通过AES密码发送给它的数据进行编码。
但是,我给出的唯一示例代码是Node.js代码。
我想,在PHP中重新实现它有多难?
很难显然。
您可以在下面看到这两种方法,但您也可以看到不同的结果。
谁知道可能会出错?
var crypto = require('crypto');
var algorithm = 'aes-128-ctr';
function encrypt(text, password) {
const key = Buffer.from(password, "hex").slice(0, 16);
const ivBuffer = Buffer.alloc(16);
const cipher = crypto.createCipheriv(algorithm, key, ivBuffer);
let crypted = cipher.update(text, "utf8", 'hex');
crypted += cipher.final('hex');
console.log(crypted);
}
encrypt('test','ed8f68b144f94c30b8add43276f0fa14');
结果:3522ca23
function encrypt($text, $password) {
$iv = "0000000000000000";
$encrypted = openssl_encrypt($text, 'aes-128-ctr', $password, OPENSSL_RAW_DATA, $iv);
return bin2hex($encrypted);
}
echo encrypt('test', 'ed8f68b144f94c30b8add43276f0fa14');
结果:8faa39d2
在浏览相关部分时(在我的帖子之后),我遇到了这个:C# and PHP have different AES encryption results
正如上面的t-m-adam所提到的,显然我需要在两个例子中对齐iv和密码。在PHP中,我的iv和密码是“常规”字符串,它们应该是与密码块大小相同长度的二进制字符串。我的iv应该(在我的情况下)是16个零字节而不是16个0字符。您可以通过以下代码的回显来查看差异:
$iv = "00000000000000000000000000000000";
echo $iv;
echo strlen($iv);
$iv = pack("H*", "00000000000000000000000000000000");
echo $iv;
echo strlen($iv);
两个$ iv变量的长度为16(由AES请求),但第二个版本由0字节组成,实际上是不可打印的。
没有进一步的麻烦,最终结果,在PHP中工作:
function encrypt($text, $password) {
$iv = pack("H*", "00000000000000000000000000000000");
$password = pack("H*", $password);
$encrypted = openssl_encrypt($text, 'aes-128-ctr', $inputKey, OPENSSL_RAW_DATA, $iv);
return bin2hex($encrypted);
}
echo encrypt('test', 'ed8f68b144f94c30b8add43276f0fa14');
结果:3522ca23
成功!!