PHP-'openssl_decrypt'函数期望什么?

时间:2019-06-13 22:49:14

标签: php encryption encoding aes

(抱歉,我不是英语为母语的人)

我已经通过AES-256-ECB加密了数据,我使用了'openssl_decrypt'函数,但是我总是收到错误的值。

$encrypted = '86090e16c5d950a35efe801f8eb5201b';
$key = 'PasswordExample_PasswordExample_';
$text = openssl_decrypt($encrypted, 'aes-256-ecb', $key);
echo "Result: $text";

我尝试使用OPENSSL_RAW_DATA选项,并用$encrypted传递了$keybase64_encode(),但是没有任何效果。

一个朋友正在通过软件向我发送此加密文本,我可以在以下站点上阅读答案:http://aes.online-domain-tools.com/.:Text example:.),但我想使用PHP进行自动化处理。

有人可以帮助我吗?我认为PHP网页上没有关于此功能的足够文档。


更新:

此测试代码显示了我的问题:

<?php

$encrypted_hex = '86090e16c5d950a35efe801f8eb5201b';
$encrypted_str = pack("H*", $encrypted_hex);
$encrypted_64 = base64_encode($encrypted_str);

echo "Encrypted (str): '$encrypted_str'<br>\n";
echo "Encrypted (hex): '$encrypted_hex'<br>\n";
echo "Encrypted (64): '$encrypted_64'<br>\n";
echo "<br>\n";

$key_str = 'PasswordExample_PasswordExample_';
$key_hex = implode(unpack("H*", $key_str));
$key_64 = base64_encode($key_str);

echo "Key (str): '$key_str'<br>\n";
echo "Key (hex): '$key_hex'<br>\n";
echo "Key (64): '$key_64'<br>\n";
echo "<br>\n";

$result_str = openssl_decrypt($encrypted_str, 'aes-256-ecb', $key_str);
$result_hex = openssl_decrypt($encrypted_hex, 'aes-256-ecb', $key_hex);
$result_64 = openssl_decrypt($encrypted_64, 'aes-256-ecb', $key_64);

echo "Result (str): '$result_str'<br>\n";
echo "Result (hex): '$result_hex'<br>\n";
echo "Result (64): '$result_64'<br>\n";
echo "<br>\n";

生成的HTML是:

加密(str):'���P�^����'
加密(十六进制):'86090e16c5d950a35efe801f8eb5201b'
加密(64):'hgkOFsXZUKNe / oAfjrUgGw =='

键(str):“ PasswordExample_PasswordExample_”
密钥(十六进制):“ 50617373776f72644578616d706c655f50617373776f72644578616d706c655f”
密钥(64):'UGFzc3dvcmRFeGFtcGxlX1Bhc3N3b3JkRXhhbXBsZV8 ='

结果(str):”
结果(十六进制):”
结果(64):''

如果我添加OPENSSL_RAW_DATA,则没有变化。该问题在Windows 10和Ubuntu 18.04(均与Apache 2和PHP 7一起)上仍然存在。我的错误在哪里?有人可以向我展示使用aes-256-ecb的示例吗?

1 个答案:

答案 0 :(得分:2)

可以通过以下方式执行解密:

$result = openssl_decrypt(hex2bin($encrypted_hex), 'aes-256-ecb', $key_str, OPENSSL_RAW_DATA|OPENSSL_ZERO_PADDING);
  • 关于OPENSSL_ZERO_PADDING标志:website使用Zero-Byte-paddingopenssl_encrypt/decrypt PKCS7-padding。使用OPENSSL_ZERO_PADDING标志,可以禁用PKCS7填充。请注意,OPENSSL_ZERO_PADDING标志禁用填充,这并不意味着使用零字节填充(标志的名称有些混乱),请参见openssl_encrypt openssl,mailismagic点com 的评论。 openssl_encrypt/decrypt不直接支持零字节填充,即用户必须实现零字节填充。由于仅解密是在PHP端进行的,因此仅必须手动执行取消填充(即删除最后的零值)操作(当前在PHP代码中缺少)。对于当前的纯文本(.:Text example:.),没有注意到丢失的未填充内容,因为纯文本正好是一个块(16字节)长,因此在加密过程中不会发生零字节填充(在与PKCS7-padding(其中附加了一个完整的块)形成对比。

  • 关于OPENSSL_RAW_DATA标志:密文不是Base64编码的,因此必须设置OPENSSL_RAW_DATA标志。或者:

    $result = openssl_decrypt(base64_encode(hex2bin($encrypted_hex)), 'aes-256-ecb', $key_str, OPENSSL_ZERO_PADDING);
    

    可用于解密。

  • 关于第一个参数:由于密文存储为十六进制字符串,因此必须首先对其进行解码(hex2bin($encrypted_hex)pack("H*", $encrypted_hex)),如注释中所述。