PHP Conference Japan 2024

openssl_decrypt

(PHP 5 >= 5.3.0, PHP 7, PHP 8)

openssl_decrypt解密数据

描述

openssl_decrypt(
    字符串 $data,
    字符串 $cipher_algo,
    #[\SensitiveParameter] 字符串 $passphrase,
    整数 $options = 0,
    字符串 $iv = "",
    ?字符串 $tag = null,
    字符串 $aad = ""
): 字符串|false

使用给定的方法和密码短语解密原始或 Base64 编码的字符串。

参数

data

要解密的加密消息。

cipher_algo

密码方法。有关可用密码方法的列表,请使用 openssl_get_cipher_methods()

passphrase

密码短语。如果密码短语短于预期,则会静默填充 NUL 字符;如果密码短语长于预期,则会静默截断。

警告

passphrase 未使用密钥派生函数,这与它的名称可能暗示的相反。唯一使用的操作是在长度不同于预期时使用 NUL 字符填充或截断。

options

options 可以是 OPENSSL_RAW_DATAOPENSSL_ZERO_PADDINGOPENSSL_DONT_ZERO_PAD_KEY

iv

null 初始化向量。如果 IV 短于预期,则会用 NUL 字符填充并发出警告;如果密码短语长于预期,则会截断并发出警告。

tag

AEAD 密码模式下的身份验证标签。如果它不正确,则身份验证失败,并且函数返回 false

警告

tag 的长度不会由函数检查。调用者有责任确保标签的长度与调用 openssl_encrypt() 时检索到的标签的长度匹配。否则,如果给定的标签仅与正确标签的开头匹配,则解密可能会成功。

aad

其他经过身份验证的数据。

返回值

成功时返回解密后的字符串,失败时返回 false

错误/异常

如果通过 cipher_algo 参数传递未知的密码算法,则会发出 E_WARNING 级别的错误。

如果通过 iv 参数传递空值,则会发出 E_WARNING 级别的错误。

变更日志

版本 描述
8.1.0 tag 现在可以为空。
7.1.0 添加了 tagaad 参数。

参见

添加注释

用户贡献的注释 4 条注释

Hernanibus
8 年前
参数对某些人来说可能很明显,但对其他人来说并非如此,所以

- $data 可以像描述中所说的那样是原始数据或 Base64 编码数据。如果没有设置 $option(也就是说,如果在此参数中传递值 0),则将假定数据为 Base64 编码。如果设置了 OPENSSL_RAW_DATA 参数,则将理解为原始数据。

- $password(密钥)是 [伪] 字节的字符串,例如由 openssl_random_pseudo_bytes() 函数生成的那些。

- $options(截至 2016 年)有两个可能的值 OPENSSL_RAW_DATA 和 OPENSSL_ZERO_PADDING。可以通过 OPENSSL_RAW_DATA|OPENSSL_ZERO_PADDING 来设置两者。如果没有指定 OPENSSL_ZERO_PADDING,则将使用 PKCS#7 的默认填充,正如 [openssl at mailismagic dot com] 在 openssl_encrypt() 中的评论中观察到的那样

- $iv 与 $password 的情况一样,是一个字节字符串。它的长度取决于使用的算法。生成 $iv 的最佳方法可能是

<?php
$iv
= openssl_random_pseudo_bytes(openssl_cipher_iv_length('您的算法'));// 例如您的算法 = 'AES-256-CTR'
?>
lucianonapoli at yahoo dot it
7 年前
参数字符串 $password 必须为二进制形式,并且派生自十六进制密钥值。

示例

在命令行控制台中使用 openssl 加密
openssl AES-256-CBC -K 5ae1b8a17bad4da4fdac796f64c16ecd -iv 34857d973953e44afb49ea9d61104d8c -in doc.txt -out doc.enc.txt

在 PHP 中解密
$key = hex2bin('5ae1b8a17bad4da4fdac796f64c16ecd');
$iv = hex2bin('34857d973953e44afb49ea9d61104d8c');

$output = openssl_decrypt($encstr, 'AES-256-CBC', $key, OPENSSL_RAW_DATA, $iv);
ittasks at gmail dot com
11 年前
如果托管服务不提供 openssl_encrypt 解密函数 - 可以通过命令提示符执行来模拟
这些函数将检查 openssl 是否已安装,并尝试默认使用它

function sslPrm()
{
return array("您的密码","IV(可选)","aes-128-cbc");
}
function sslEnc($msg)
{
list ($pass, $iv, $method)=sslPrm();
if(function_exists('openssl_encrypt'))
return urlencode(openssl_encrypt(urlencode($msg), $method, $pass, false, $iv));
else
return urlencode(exec("echo \"".urlencode($msg)."\" | openssl enc -".urlencode($method)." -base64 -nosalt -K ".bin2hex($pass)." -iv ".bin2hex($iv)));
}
function sslDec($msg)
{
list ($pass, $iv, $method)=sslPrm();
if(function_exists('openssl_decrypt'))
return trim(urldecode(openssl_decrypt(urldecode($msg), $method, $pass, false, $iv)));
else
return trim(urldecode(exec("echo \"".urldecode($msg)."\" | openssl enc -".$method." -d -base64 -nosalt -K ".bin2hex($pass)." -iv ".bin2hex($iv))));
}

// 用法示例
$r= sslEnc("这是一个加密/解密测试!");
echo "<br>\n".$r.":".sslDec($r);
markagius dot co dot uk
7 年前
openssl_decrypt(..) 对大多数方法类型有效,但并非所有类型都适用。
此列表可能有所不同,具体取决于使用的 数据(消息)和 密钥(密码)。

请参阅以下代码并编辑 $text 和 $password 值。
代码检查加密后解密后的文本是否相同。

注意
您仍然可以使用 openssl_encrypt(..) 与;
用户输入“登录密码”
(使用 openssl_encrypt 加密并存储)
下次。
用户使用“登录密码”登录
(检查加密的“登录密码”是否等于存储的数据)



<CODE>
// 请编辑 $password=... 和 $text=...

$password = "This is a journey into sound";

$text = "";
for($charNo=0; $charNo<=255; $charNo=$charNo+1){
// if($charNo==127) {$charNo=$charNo+1;}
if(!$charNo<127){
// $text = $text."&#x".strtoupper(dechex($charNo)).";";
$text = $text.chr($charNo);
} else {
$text = $text.chr($charNo);
}
}

$text = "This is a test message.";

print "<TABLE BORDER=\"1\">\n";
print "<TR><TD><B>加密类型:</B></TD><TD><B>转换回后的字符串:</B></TD></TR>\n";
$ciphers = openssl_get_cipher_methods();
for($pointer=0; $pointer<count($ciphers); $pointer=$pointer+1){
$edit = EncryptDecrypt($text, true, $password, $ciphers[$pointer]);
$check = EncryptDecrypt($edit, false, $password, $ciphers[$pointer]);
if($text!=$check){
$info = $check;
print "<TR><TD>".$ciphers[$pointer]."</TD><TD>".$info."</TD></TR>\n";
}
}
print "</TABLE>\n";

function EncryptDecrypt($oldText, $encryptIt=true, $password="PASSWORD", $encryptType=""){
$ciphers = openssl_get_cipher_methods();
$foundEncType = false;
for($pointer=0; $pointer<count($ciphers); $pointer=$pointer+1){
if($ciphers[$pointer]==$encryptType){$foundEncType=true;}
}
if(!$foundEncType){
$encryptType = "RC2-64-CBC"; // 未设置或未列出时使用的默认值。
}
if($encryptIt){
$newText = openssl_encrypt($oldText,$encryptType,$password);
} else {
$newText = openssl_decrypt($oldText,$encryptType,$password);
}
return $newText;
}
</CODE>
以下(有时)不起作用
DES-EDE3-CFB1(有时)
aes-128-gcm
aes-192-gcm
aes-256-gcm
des-ede3-cfb1(有时)
id-aes128-GCM
id-aes192-GCM
id-aes256-GCM
To Top