[英]openssl_decrypt() can't decrypt text encrypted on the commandline
出于测试目的,我编写了encrypt.bash
和decrypt.bash
,以证明保存到encrypted.txt
中的加密数据可以成功解密。
以下是 bash 文件:
加密.bash
#!/bin/bash
message="This is my message, I hope you can see it. It's very long now."
key="sup3r_s3cr3t_p455w0rd"
echo "$message" | openssl enc \
-aes-256-ctr \
-e \
-k "$key" \
-iv "504914019097319c9731fc639abaa6ec" \
-out encrypted.txt
解密.bash
#!/bin/bash
key="sup3r_s3cr3t_p455w0rd"
decrypted=$(openssl enc \
-aes-256-ctr \
-d \
-k "$key" \
-iv "504914019097319c9731fc639abaa6ec" \
-in encrypted.txt)
echo "Decrypted message: $decrypted"
运行bash decrypt.bash
输出以下内容:
解密消息:这是我的消息,希望你能看到。 现在很长。
我正在努力的地方是使用 PHP 读取encrypted.txt
文件并使用openssl_decrypt
对其进行解密。 据我所知,我使用所有相同的设置,并正确处理二进制数据,但显然我做错了什么。
解密.php
<?php
$key = "sup3r_s3cr3t_p455w0rd";
$encrypted = file_get_contents("encrypted.txt");
$iv = hex2bin("504914019097319c9731fc639abaa6ec");
$decrypted = openssl_decrypt(
$encrypted,
"aes-256-ctr",
$key,
0,
$iv,
);
echo "Decrypted message: $decrypted";
运行php decrypt.php
输出以下内容:
解密消息:��c�������Pb�j��
像这样归结起来似乎很简单,但我很难找出代码中存在的错误。
-k 选项不指定密钥,而是指定密码。 从此密码和随机生成的 8 字节盐一起,使用派生函数EVP_BytesToKey()
派生密钥。 加密后的数据以 OpenSSL 格式返回,该格式由Salted__
的 ASCII 编码,后跟 8 个字节的 salt 和实际密文组成。
这个密钥派生函数的简化 PHP 实现在这里就足够了(因为这里用 -iv 明确指定了 IV,所以它不与密钥一起派生):
// from: https://gist.github.com/ezimuel/67fa19030c75052b0dde278a383eda1b
function EVP_BytesToKey($salt, $password) {
$bytes = '';
$last = '';
// 32 bytes key
while(strlen($bytes) < 32) {
$last = hash('sha256', $last . $password . $salt, true); // md5 before v1.1.0
$bytes.= $last;
}
return $bytes;
}
提取盐和实际密文是:
$password = "sup3r_s3cr3t_p455w0rd";
$encrypted = file_get_contents("<path to enc file>");
$salt = substr($encrypted, 8, 8);
$key = EVP_BytesToKey($salt, $password);
$ciphertext = substr($encrypted, 16);
此外,由于传递的是原始数据,因此必须设置相应的OPENSSL_RAW_DATA
标志:
$iv = hex2bin("504914019097319c9731fc639abaa6ec");
$decrypted = openssl_decrypt($ciphertext, "aes-256-ctr", $key, OPENSSL_RAW_DATA, $iv);
请注意,从 OpenSSL v1.1.0 开始,默认摘要是 SHA256,在 MD5 之前。 为了兼容性, EVP_BytesToKey()
中使用的摘要必须相同。 还要注意EVP_BytesToKey()
现在被认为是不安全的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.