使用 AES-256 加密时输出为空?
Empty output when encrypting with AES-256?
我有一个用 AES 128 CBC 加密的字符串,我需要对其进行解密。我有钥匙,似乎可以正常工作。问题出在初始化向量 (IV) 上。
IV 长 16 个字节,
B409678003171307B8B8B8B8B8B8B8B8
但是当我将它添加到我的脚本时,OpenSSL 截断它说它是 32 长,如下所示:
openssl_decrypt(): IV passed is 32 bytes long which is longer than the 16 expected by selected cipher, truncating
我想这意味着它有 32 个字符长 - 但我如何让它理解它只有 16 个字节?
更新:在 IV 上使用 hex2bin 解决了截断问题 - 但我的 openssl_decrypt 没有产生任何结果。还在键上做了 hex2bin,仍然没有输出。简化代码,更容易发现问题:
<?php
$str = "7F53B967F1BF7C9EC26B0C405E453ABD";
$k = "F71D4590A6E6E219EBBE8BFE9D3DC21A";
$intv = "B409678003171307B8B8B8B8B8B8B8B8";
$key = hex2bin($k);
$iv = hex2bin($intv);
$plaintext = openssl_decrypt($str, 'AES-128-CBC', $key, OPENSSL_RAW_DATA, $iv);
print_r($plaintext);
?>
那么,hex2bin 是不是走错了路?还是我使用 openssl_decrypt 的方式有问题? PHP error_log.
中没有错误
提前致谢!
好的,这似乎实现了与 OP 链接的基于 Web 的服务相同的结果。关键步骤是
a) 除了 $k 和 $intv,确保你也将加密的 $str 从它的十六进制表示转换为二进制
b) 提供额外标志 OPENSSL_ZERO_PADDING
c) 当你回显或 var_dump 或 print_r 输出时,确保你转换回十六进制以便输出可读
$encrypted = "7F53B967F1BF7C9EC26B0C405E453ABD";
$k = "F71D4590A6E6E219EBBE8BFE9D3DC21A";
$intv = "B409678003171307B8B8B8B8B8B8B8B8";
$str = hex2bin($encrypted);
$key = hex2bin($k);
$iv = hex2bin($intv);
$decrypted = openssl_decrypt($str, 'AES-128-CBC', $key, OPENSSL_RAW_DATA|OPENSSL_ZERO_PADDING, $iv);
$str_decrypted = bin2hex($decrypted);
var_dump($str_decrypted);
输出:
string(32) "2f2f0c1335000000046d372b27230f15"
注意:我不能确定这实际上是原始加密数据的解密形式。它恰好与基于网络的服务相匹配。我假设您链接的值实际上是正确的值。只需将 OPENSSL_ZERO_PADDING 标志添加到原始代码即可消除错误,但输出会有所不同。也许尝试一些实验。
我有一个用 AES 128 CBC 加密的字符串,我需要对其进行解密。我有钥匙,似乎可以正常工作。问题出在初始化向量 (IV) 上。
IV 长 16 个字节,
B409678003171307B8B8B8B8B8B8B8B8
但是当我将它添加到我的脚本时,OpenSSL 截断它说它是 32 长,如下所示:
openssl_decrypt(): IV passed is 32 bytes long which is longer than the 16 expected by selected cipher, truncating
我想这意味着它有 32 个字符长 - 但我如何让它理解它只有 16 个字节?
更新:在 IV 上使用 hex2bin 解决了截断问题 - 但我的 openssl_decrypt 没有产生任何结果。还在键上做了 hex2bin,仍然没有输出。简化代码,更容易发现问题:
<?php
$str = "7F53B967F1BF7C9EC26B0C405E453ABD";
$k = "F71D4590A6E6E219EBBE8BFE9D3DC21A";
$intv = "B409678003171307B8B8B8B8B8B8B8B8";
$key = hex2bin($k);
$iv = hex2bin($intv);
$plaintext = openssl_decrypt($str, 'AES-128-CBC', $key, OPENSSL_RAW_DATA, $iv);
print_r($plaintext);
?>
那么,hex2bin 是不是走错了路?还是我使用 openssl_decrypt 的方式有问题? PHP error_log.
中没有错误提前致谢!
好的,这似乎实现了与 OP 链接的基于 Web 的服务相同的结果。关键步骤是 a) 除了 $k 和 $intv,确保你也将加密的 $str 从它的十六进制表示转换为二进制 b) 提供额外标志 OPENSSL_ZERO_PADDING c) 当你回显或 var_dump 或 print_r 输出时,确保你转换回十六进制以便输出可读
$encrypted = "7F53B967F1BF7C9EC26B0C405E453ABD";
$k = "F71D4590A6E6E219EBBE8BFE9D3DC21A";
$intv = "B409678003171307B8B8B8B8B8B8B8B8";
$str = hex2bin($encrypted);
$key = hex2bin($k);
$iv = hex2bin($intv);
$decrypted = openssl_decrypt($str, 'AES-128-CBC', $key, OPENSSL_RAW_DATA|OPENSSL_ZERO_PADDING, $iv);
$str_decrypted = bin2hex($decrypted);
var_dump($str_decrypted);
输出:
string(32) "2f2f0c1335000000046d372b27230f15"
注意:我不能确定这实际上是原始加密数据的解密形式。它恰好与基于网络的服务相匹配。我假设您链接的值实际上是正确的值。只需将 OPENSSL_ZERO_PADDING 标志添加到原始代码即可消除错误,但输出会有所不同。也许尝试一些实验。