2024 PHP Conference Japan

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 現在可以為 null。
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('your algorithm'));// 例如,您的演算法 = '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 和 decrypt 函式,可以透過命令提示執行來模擬。
此函式將檢查是否安裝了 openssl,並嘗試預設使用它。

function sslPrm()
{
return array("your_password","IV (optional)","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 = "這是一趟聲音之旅";

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

$text = "這是一個測試訊息。";

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 {
} 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