我试图通过Windows命令提示符加密一个字符串(openssl 256-cbc),并在PHP中解密结果。
我通过以下方式进行了加密:
echo {un:est@test.com,upass:klkKJS*dfd!j@d76w} | openssl enc -e -aes-256-cbc -a -salt -pass pass:sw8/M!CLl:=cmgtHts?v/Wb7C$Vk9Sy-{go.*+E;[GAg~KQi*rI!1#z;x/KT为了解密,我的php代码是:
$ivlen = openssl_cipher_iv_length('aes-256-cbc');
$iv = openssl_random_pseudo_bytes($ivlen);
echo openssl_decrypt('U2FsdGVkX18ruQUgA9LEOOvdOUQXv/o8z6ZNO820MKzSIbMjFcyfNo1efQwAOINxMY9+UxZjxaT+JEWmlUyYQw==', 'aes-256-cbc', 'sw8/M!CLl:=cmgtHts?v/Wb7C$Vk9Sy-{go.*+E;[GAg~KQi*rI!1#z;x/KT', $options=0, $iv);但是解密的字符串是空的。请帮帮忙。
(注意:我还需要做反向过程,即用php加密和从WIN命令提示符解密。因此,请添加任何可能有用的建议。)
发布于 2022-02-20 22:05:58
OpenSSL语句在加密过程中生成一个随机的8字节盐,它与密码一起用于派生一个32字节的密钥和一个带有OpenSSL函数EVP_BytesToKey()的16字节IV。
使用密钥和IV在CBC模式下使用AES-256执行加密.结果包括Salted__的ASCII编码的级联,然后是salt和实际的密文(所有Base64编码)。
PHP/OpenSSL中的解密必须按以下方式实现:
EVP_BytesToKey()获取密钥和IV。一个可能的执行是:
<?php
function EVP_BytesToKey($salt, $password) {
$bytes = '';
$last = '';
while(strlen($bytes) < 48) {
$last = hash('md5', $last . $password . $salt, true);
$bytes.= $last;
}
return $bytes;
}
$saltCiphertext = base64_decode('U2FsdGVkX18ruQUgA9LEOOvdOUQXv/o8z6ZNO820MKzSIbMjFcyfNo1efQwAOINxMY9+UxZjxaT+JEWmlUyYQw==');
$salt = substr($saltCiphertext, 8, 8);
$ciphertext = substr($saltCiphertext, 16);
$keyIv = EVP_BytesToKey($salt, 'sw8/M!CLl:=cmgtHts?v/Wb7C$Vk9Sy-{go.*+E;[GAg~KQi*rI!1#z;x/KT');
$key = substr($keyIv, 0, 32);
$iv = substr($keyIv, 32);
echo openssl_decrypt($ciphertext, 'aes-256-cbc', $key, OPENSSL_RAW_DATA, $iv); // {un:est@test.com,upass:klkKJS*dfd!j@d76w}
?>在早期版本中,OpenSSL默认使用MD5作为EVP_BytesToKey()摘要,版本为V1.1.0 SHA256。在发布的示例中,使用MD5解密是成功的,因此显然在加密中使用了MD5。
请注意,现在使用EVP_BytesToKey()进行密钥派生被认为是不安全的。
发布于 2022-02-21 07:41:28
正如@Topaco对通过命令提示符编码的字符串进行PHP解密所建议的那样,下面是一个相反的例子( in命令行)。感谢@Topaco的评论和这段代码。
<?php
function EVP_BytesToKey($salt, $password) {
$bytes = '';
$last = '';
while(strlen($bytes) < 48) {
$last = hash('md5', $last . $password . $salt, true);
$bytes.= $last;
}
return $bytes;
}
$saltDeciphertext= '{un:est@test.com,upass:klkKJS*dfd!j@d76w}';
$crypttext = "Salted__";
$salt= random_bytes(8);
$crypttext .= $salt;
$keyIV= EVP_BytesToKey($salt, 'sw8/M!CLl:=cmgtHts?v/Wb7C$Vk9Sy-{go.*+E;[GAg~KQi*rI!1#z;x/KT');
$key = substr($keyIV, 0, 32);
$iv = substr($keyIV, 32);
$crypttext .= openssl_encrypt($saltDeciphertext, 'AES-256-CBC', $key, OPENSSL_RAW_DATA, $iv);
echo base64_encode($crypttext);
?>随后的解密命令:
echo U2FsdGVkX1+rDCycmwvc6rImKmrzaC9WTlzFanXt476975aYQcxPt2fgnRazm7CorGkpAWm9vmcu33YpiTYziw== | openssl enc -d -aes-256-cbc -a -salt -pass pass:sw8/M!CLl:=cmgtHts?v/Wb7C$Vk9Sy-{go.*+E;[GAg~KQi*rI!1#z;x/KThttps://stackoverflow.com/questions/71198954
复制相似问题