我有一个用AES 128 CBC加密的字符串,我需要解密。我有一把似乎工作得很好的钥匙。问题在于初始化向量(IV)。
IV长度为16个字节,
B409678003171307B8B8B8B8B8B8B8B8
但是当我将它添加到我的脚本中时,OpenSSL会截断它,说它长32就像这样:
openssl_decrypt():传递的IV长度为32个字节,比选定密码所期望的16个字节长,截断
我想这意味着它的长度为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中没有错误。
提前致谢!
答案 0 :(得分:1)
确定这似乎与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"
注意:我无法确定这实际上是原始加密数据的解密形式。它只是匹配基于Web的服务。我假设您链接的值实际上是正确的值。只需将OPENSSL_ZERO_PADDING标志添加到原始代码中即可消除错误,但输出会有所不同。也许尝试一些实验。