在 Web 開發中,常需對敏感資料(如 API Token、用戶識別碼)進行可逆加密,以便在前後端或系統間安全傳輸。本文介紹一個基於 XOR 位運算與 MD5 雜湊的輕量級加密類,無需擴展庫即可部署,適合中小型專案快速集成。
演算法採用「一次性密碼本」思想:以 MD5 雜湊值作為密鑰流,對明文逐字元進行 XOR 運算。為抵抗已知明文攻擊,引入隨機種子生成會話密鑰,並將種子資訊隱藏於密文頭部,形成「加密封包」。解密時先提取種子還原密鑰流,再反向 XOR 還原明文。
<?php
$key = "This is supposed to be a secret key !!!";
function keyED($txt, $encrypt_key) {
$encrypt_key = md5($encrypt_key);
$ctr = 0;
$tmp = "";
for ($i = 0; $i < strlen($txt); $i++) {
if ($ctr == strlen($encrypt_key)) $ctr = 0;
$tmp .= substr($txt, $i, 1) ^ substr($encrypt_key, $ctr, 1);
$ctr++;
}
return $tmp;
}
function encrypt($txt, $key) {
srand((double)microtime() * 1000000);
$encrypt_key = md5(rand(0, 32000));
$ctr = 0;
$tmp = "";
for ($i = 0; $i < strlen($txt); $i++) {
if ($ctr == strlen($encrypt_key)) $ctr = 0;
$tmp .= substr($encrypt_key, $ctr, 1) .
(substr($txt, $i, 1) ^ substr($encrypt_key, $ctr, 1));
$ctr++;
}
return keyED($tmp, $key);
}
function decrypt($txt, $key) {
$txt = keyED($txt, $key);
$tmp = "";
for ($i = 0; $i < strlen($txt); $i++) {
$md5 = substr($txt, $i, 1);
$i++;
$tmp .= (substr($txt, $i, 1) ^ $md5);
}
return $tmp;
}
// 測試範例
$string = "Hello World !!!";
$enc_text = encrypt($string, $key);
$dec_text = decrypt($enc_text, $key);
echo "Original text : $string <br>";
echo "Encrypted text : $enc_text <br>";
echo "Decrypted text : $dec_text <br>";
?>
encrypt() 先用隨機密鑰流 XOR 明文並將密鑰流插入密文(形成帶種子的中間文本),再用主密鑰 $key 經 keyED() 二次加密。雙重保障極大增加破解難度。srand((double)microtime()*1000000) 結合 rand(0,32000) 生成高熵種子,確保相同明文每次加密結果不同,防範彩虹表攻擊。decrypt() 先用主密鑰還原中間文本,再按「取一字節作密鑰、取下一字節 XOR 還原」的順序提取明文,精確對應加密過程。⚠️ 注意:此演算法屬於對稱加密,密鑰洩露將導致全量數據風險。生產環境建議:
$key 僅存於伺服器端環境變數,嚴禁寫入代碼倉庫。sodium_crypto_secretbox()(Libsodium),兼具高效能與抗旁路攻擊特性。