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

使用AES-128-CTR加密在PHP(openssl_encrypt)和Node.js(crypto)上给出不同的结果,php,node.js,encryption,aes,Php,Node.js,Encryption,Aes,我有一个API,它要求我对通过AES密码发送给它的数据进行编码 但是,我得到的唯一示例代码是Node.js代码 我想,在PHP中重新实现它有多难 显然很难 下面您可以看到这两种方法,但也可以看到不同的结果 有人知道可能出了什么问题吗 NODE.js版本 结果:3522ca23 PHP版本 结果:8faa39d2在浏览相关部分(在我的帖子之后)时,我遇到了以下内容: 正如上面提到的,显然我需要在两个示例中对齐iv和密码。在PHP中,my iv和password是“常规”字符串,它们应该是与密码块

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

但是,我得到的唯一示例代码是Node.js代码

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

显然很难

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

有人知道可能出了什么问题吗

NODE.js版本 结果:3522ca23

PHP版本
结果:8faa39d2

在浏览相关部分(在我的帖子之后)时,我遇到了以下内容:

正如上面提到的,显然我需要在两个示例中对齐iv和密码。在PHP中,my iv和password是“常规”字符串,它们应该是与密码块大小相同长度的二进制字符串。我的iv(在我的例子中)应该是16个零字节,而不是16 x 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


成功

您使用的是不同的key和IV。在PHP中,您并没有对密钥进行十六进制解码,所以它是一个32字节的a-f0-9字符串。另外,PHP中的IV是16个零字符,而不是16个零字节。在浏览相关部分时,我已经找到了一个似乎符合您逻辑的解决方案。谢谢你的回复!!没问题!你知道,如果你认为答案对其他人有用的话,你可以发布一个答案。我刚刚发布了,请随意看看我是否正确理解了我的错误:)这可能会很有帮助!!如果您需要一些建议,您可以通过使用随机IV和算法来改进加密。最近我用GCM回答了一个类似的问题。如果你愿意的话,你可以找到它。我必须把它传递给实现API的人(另一家公司)。根据我从你的例子(以及我的直觉)中收集到的信息,这意味着我们必须发送用于加密数据本身的$iv,才能解密它,对吗?随机$iv的目的是减少“可破解性”,就像一种盐?是的,iv必须是不可预测的,但它不一定是秘密的,你可以用密文发送它(如果你选择使用经过身份验证的加密,还可以使用标签)。我找不到任何来源,但我认为当IV被重用时,CTR容易受到攻击。好的,我在CTR上找到了一篇RFC3686文章。参见第四章,了解安全性。
$iv = "00000000000000000000000000000000";
echo $iv;
echo strlen($iv);

$iv = pack("H*", "00000000000000000000000000000000");
echo $iv;
echo strlen($iv);
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');