AES-128-CTR加密在PHP(openssl_encrypt)和Node.js(加密)上给出不同的结果

问题描述 投票:2回答:1

我有一个API,要求我对通过AES密码发送给它的数据进行编码。

但是,我给出的唯一示例代码是Node.js代码。

我想,在PHP中重新实现它有多难?

很难显然。

您可以在下面看到这两种方法,但您也可以看到不同的结果。

谁知道可能会出错?

NODE.js版本

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

PHP版本

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

php node.js encryption aes
1个回答
1
投票

在浏览相关部分时(在我的帖子之后),我遇到了这个: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

成功!!

© www.soinside.com 2019 - 2024. All rights reserved.