在早期的 PHP 開發中,資料加密與解密是常見需求。本文介紹一種結合 MD5 雜湊與 MCrypt 擴展的對稱加密演示,雖然 MCrypt 已在 PHP 7.2 中移除,但理解其原理對維護舊專案或學習加密概念仍有價值。
以下範例展示了使用 DES 演算法(ECB 模式)進行加解密的完整流程:
// 加密函式
function string2secret($str) {
$key = "123"; // 密鑰種子
$td = mcrypt_module_open(MCRYPT_DES, '', 'ecb', '');
$iv = mcrypt_create_iv(mcrypt_enc_get_iv_size($td), MCRYPT_RAND);
$ks = mcrypt_enc_get_key_size($td);
// 取 MD5 前 $ks 位作為實際金鑰
$key = substr(md5($key), 0, $ks);
mcrypt_generic_init($td, $key, $iv);
$secret = mcrypt_generic($td, $str);
mcrypt_generic_deinit($td);
mcrypt_module_close($td);
return $secret;
}
// 解密函式
function secret2string($sec) {
$key = "123";
$td = mcrypt_module_open(MCRYPT_DES, '', 'ecb', '');
$iv = mcrypt_create_iv(mcrypt_enc_get_iv_size($td), MCRYPT_RAND);
$ks = mcrypt_enc_get_key_size($td);
$key = substr(md5($key), 0, $ks);
mcrypt_generic_init($td, $key, $iv);
$string = mdecrypt_generic($td, $sec);
mcrypt_generic_deinit($td);
mcrypt_module_close($td);
return trim($string);
}
// 測試
echo secret2string(string2secret("11111111111111111")); // 輸出原文
echo string2secret("11111111111111111"); // 輸出密文(亂碼)
md5($key) 產生 32 字元十六進位字串,再截取演算法所需長度(DES 為 8 位元組)。mcrypt_generic_init → 加解密 → mcrypt_generic_deinit → mcrypt_module_close 的生命週期。PHP 7.1+ 建議改用 OpenSSL 或 Sodium (libsodium) 擴展:
// 使用 OpenSSL AES-256-CBC 範例
$key = hash('sha256', 'my_secret_key', true);
$iv = random_bytes(16);
$ciphertext = openssl_encrypt($plaintext, 'AES-256-CBC', $key, OPENSSL_RAW_DATA, $iv);
// 儲存時將 $iv 與 $ciphertext 組合(如 base64_encode($iv.$ciphertext))
實務上常搭配 base64_encode / base64_decode 將二進位密文轉為可安全傳輸的字串。
更多 PHP 加解密技巧請參考專題:《PHP 加密方法總結》