当前位置: 首页 > 知识库问答 >
问题:

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

谭新知
2023-03-14

我有一个 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

共有1个答案

江敏学
2023-03-14

在浏览相关部分时(在我的帖子之后),我发现了这个:C#和PHP有不同的AES加密结果

正如上面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

成功!!

 类似资料:
  • 问题内容: 我们遇到了一种奇怪的情况,尽管我们在Java中使用的加密方法在配置上看起来完全相同,但它们生成的输出却与openssl不同。 使用相同的键和IV,文本“快速的棕狐狸跳过了懒狗!” 加密为base64的字符串… openssl: Java: 这是我们的openssl电话… 这是我们的Java … oopenssl输出 Java输出 我们缺少明显的东西吗?还是存在一些隐藏的复杂性? 问题答

  • 我们遇到了一个奇怪的情况,我们在Java中使用的加密方法产生了与openssl不同的输出,尽管它们在配置上看起来相同。 使用相同的键和IV,文本“敏捷的棕色狐狸跳过懒惰的狗!”加密到base64的字符串。。。 openssl: Java: 我们错过了什么明显的东西吗?还是有一些隐藏的复杂性?

  • 我有这段代码,它基本上对两条纯文本消息进行加密,然后尝试解密,然后打印。问题是第一条消息恢复得很好,但第二条消息是垃圾。我从本教程下载了这段代码,然后将其修改为使用字符串而不是文件,因为我需要它通过套接字发送加密文本。所以其他endpoint不知道明文的长度,有没有办法找到长度,或者我必须以某种方式将明文的长度与密码一起发送? 现在,我认为解密的中断条件有问题。 另外,main()代码在概念上是否

  • 我不是openssl的专家。我把下面的代码放在一起,使用AES-CTR加密和解密消息。输出不是我期望看到的。 我得到的结果是这样的:“简单:、u∩U└■我的 知道是什么导致的吗?我想做的就是使用AES使用CTR来加密和解密消息。我想得到与纯文本相同的加密长度(或1字节)。我用DES做过这个,但是DES不安全。然后,我将使用AES-CTR加密和解密我的流量(流)。

  • 我使用的是128位的AES ALgo,带有CBC密码模式加密,下面是代码: 但这给了我一个警告,输出为: 警告:mcrypt_generic_init():密钥大小太大;提供的长度:64,最大:32 /var/www/cipher.php第10行警告:mcrypt_generic_init():密钥大小太大;提供的长度:64,最大:32 /var/www/cipher.php第14行加密:vM/X

  • 问题内容: 我一直在尝试使用AES-128 CBC解密字符串,该字符串最初是使用JAVA AES加密加密的。在Java中,使用PKCS7填充。而且我尝试使用类似的PHP代码进行加密和解密。但是我得到了不同的结果。 我的Java代码 以及我正在使用的等效PHP代码。 在Java中 纯文本= 123456 密码文本= tpyxISJ83dqEs3uw8bN / + w =​​= 在PHP中 纯文本=