2024 年 PHP Conference Japan

mcrypt_generic

(PHP 4 >= 4.0.2, PHP 5, PHP 7 < 7.2.0, PECL mcrypt >= 1.0.0)

mcrypt_generic此函式用於加密資料

警告

此函式已於 PHP 7.1.0 中被標記為 *已棄用*,並於 PHP 7.2.0 中被 *移除*。強烈建議不要使用此函式。

說明

mcrypt_generic(資源 $td, 字串 $data): 字串

此函數用於加密資料。資料會以 "\0" 進行填充,以確保資料長度為 n * 區塊大小。此函數會返回加密後的資料。請注意,由於資料的填充,返回字串的長度實際上可能比輸入長。

如果您想將加密的資料儲存在資料庫中,請務必儲存 mcrypt_generic 返回的整個字串,否則字串將無法完全正確解密。如果您的原始字串長度為 10 個字元,而區塊大小為 8(使用 mcrypt_enc_get_block_size() 函數來確定區塊大小),則您的資料庫欄位至少需要 16 個字元。請注意,mdecrypt_generic() 函數返回的字串也將是 16 個字元…使用 rtrim($str, "\0") 來移除填充。

例如,如果您將資料儲存在 MySQL 資料庫中,請記住 varchar 欄位在插入期間會自動移除尾隨空格。由於加密的資料可能以空格(ASCII 32)結尾,因此移除空格會損壞資料。請改用 tinyblob/tinytext(或更大)欄位來儲存資料。

參數

td

加密描述符。

在呼叫此函數之前,應始終使用 mcrypt_generic_init() 以金鑰和初始向量 (IV) 初始化加密控制代碼。完成加密後,您應該透過呼叫 mcrypt_generic_deinit() 來釋放加密緩衝區。請參閱 mcrypt_module_open() 範例。

data

要加密的資料。

傳回值

返回加密後的資料。

參見

新增註釋

使用者提供的註釋 7 則註釋

tmacedo at linux dot ime dot usp dot br
18 年前
補充 Ryan Thomas (ryanrst at gmail dot com) 的文章,如果您使用 HTTP 方法發送 Cookie,它可能會被編碼;
由於 base64 中的某些字元會被編碼成其他內容,您可以在編碼前和解碼後替換它們;
這是 dawgeatschikin at hotmail dot com 對 massimo dot scamarcia at gmail dot com 原始想法的調整
(請參閱 @ https://php.dev.org.tw/manual/en/function.base64-encode.php
<?php
function urlsafe_b64encode($string)
{
$data = base64_encode($string);
$data = str_replace(array('+','/','='),array('-','_','.'),$data);
return
$data;
}
function
urlsafe_b64decode($string)
{
$data = str_replace(array('-','_','.'),array('+','/','='),$string);
$mod4 = strlen($data) % 4;
if (
$mod4) {
$data .= substr('====', $mod4);
}
return
base64_decode($data);
}
?>
Ryan Thomas, ryanrst@gmail.com
18 年前
如果您想將加密資料儲存在瀏覽器的 Cookie 變數中,您在解密資料時會遇到問題。這是因為 Cookie 只會儲存 US-ASCII 字元,而您的加密資料可能包含非 US-ASCII 字元。

解決方案

在將加密字串儲存在 Cookie 之前,先使用 base64_encode 進行編碼,並在解密之前,將儲存在 Cookie 中的字串使用 base64_decode 進行解碼。

範例

function setEncryptedCookie($cookieName, $data)
{
setcookie($cookieName, base64_encode($this->encrypt($data)), time()+$this->expire);
}

function getEncryptedCookie($cookieName)
{
return $this->decrypt(base64_decode($_COOKIE[$cookieName]));
}
chad 0x40 herballure.com
18 年前
如果資料已經是 n*blocksize 的長度,PHP 會用另一個完整的 "\0" 區塊來填充,因此會有 1 到 mcrypt_enc_get_block_size($td) 個位元組的填充。

您可以透過無條件地將 0x80 添加到字串中,然後去除 PHP 添加的尾端 "\0" 以及一個 0x80 位元組,來創建二進位制安全的填充。

<?php
function pad($text) {
// 添加一個 0x80 位元組,並讓 PHP 使用 0x00 位元組填充。
return pack("a*H2", $text, "80");
}
function
unpad($text) {
// 返回已移除 0x00 位元組的文字中除了尾端 0x80 之外的所有內容
return substr(rtrim($text, "\0"), 0, -1);
}
?>
chad 0x40 herballure.com
18 年前
補充我之前的說明:顯然發生了某種字元編碼錯誤;PHP 在不需要填補時不會進行填補,而我看到的額外填補是 chr(X) 傳回多個位元組之類的結果。

不過,我提供的填補/取消填補函式仍然是二進位制安全的,而且據我所知完全相容於 NIST 800-38a。
maxximus007 at gmail dot com
17 年前
行為變更:自 5.2.x 版起,當資料字串為空時,mcrypt_generic 將發出警告。
eric at ez-llc dot com
18 年前
我成功地讓 PHP 和 Perl 使用 Blowfish 搭配密碼區塊鏈結模式(Cipher Block Chaining)一起運作。Blowfish 金鑰需要至少 8 個字元(即使 Blowfish 最短是 8 位元,Perl 也不喜歡小於 8 個字元的密鑰),最多 56 個字元。初始向量(IV)必須正好是 8 個字元,且填補方式需要是 null,因為 PHP 使用 null 進行填補。此外,PHP 需要 libmcrypt >= 2.4.9 才能與 Perl 相容。

PERL
----

use Crypt::CBC;
$cipher = Crypt::CBC->new( {'key' => 'my secret key',
'cipher'=> 'Blowfish',
'iv' => '12345678',
'regenerate_key' => 0,
'padding' => 'null',
'prepend_iv' => 0
});
$cc = 'my secret text';
$encrypted = $cipher->encrypt($cc);
$decrypted = $cipher->decrypt($encrypted);

print "encrypted : ".$encrypted;
print "<br>";
print "decrypted : ".$decrypted;

PHP
---

$cc = 'my secret text';
$key = 'my secret key';
$iv = '12345678';

$cipher = mcrypt_module_open(MCRYPT_BLOWFISH,'','cbc','');

mcrypt_generic_init($cipher, $key, $iv);
$encrypted = mcrypt_generic($cipher,$cc);
mcrypt_generic_deinit($cipher);

mcrypt_generic_init($cipher, $key, $iv);
$decrypted = mdecrypt_generic($cipher,$encrypted);
mcrypt_generic_deinit($cipher);

echo "encrypted : ".$encrypted;
echo "<br>";
echo "decrypted : ".$decrypted;
pauls at sellingsource dot com
21 年前
如果您要加密二進位制資料,並且在加密過程中出現 null 終止符,您將遺失字串的其餘部分。解決方法是先使用 base64_encode 對二進位制字串進行編碼。

我們在嘗試加密信用卡資訊時發現了這個問題。某些信用卡值在轉換為二進位制字串後無法解密。

我們使用 MCRYPT_RIJNDAEL_256 模組進行加密。

希望這對其他人有所幫助。
To Top