異或 (XOR, ^) 運算特性:A ^ B = C,則 C ^ B = A。同一組金鑰可同時用於加密與解密,屬於對稱式流式密碼。
<?php
// 原文代碼有多處語法錯誤與邏輯缺陷
function myEncrypt($string, $key) {
for($i=0; $i < strlen($string); $i++) { // 原寫 STRLEN($STRING)、p $i++、<>
for($j=0; $j < strlen($key); $j++) { // 重複對每個字元做完整金鑰 XOR,非標準做法
$string[$i] = $string[$i] ^ $key[$j];
}
}
return $string;
}
?>
問題:
STRLEN、p $i++、<> 非合法 PHP$string[$i] ^= (xor of all key bytes),金鑰長度>1 時非可逆<?php
function xor_encrypt(string $data, string $key): string {
$keyLen = strlen($key);
$result = '';
for ($i = 0; $i < strlen($data); $i++) {
$result .= $data[$i] ^ $key[$i % $keyLen];
}
return $result;
}
// 加密與解密使用相同函數
$plaintext = "Hello World";
$key = "secret_key_123";
$ciphertext = xor_encrypt($plaintext, $key);
$decrypted = xor_encrypt($ciphertext, $key);
echo "原文: $plaintext\n";
echo "密文: " . bin2hex($ciphertext) . "\n"; // 顯示十六進制避免亂碼
echo "解密: $decrypted\n";
| 弱點 | 說明 |
|---|---|
| 已知明文攻擊 | 攻擊者若知道部分明文,可推導金鑰流:key = plain ^ cipher
|
| 金鑰重用災難 | 同一金鑰加密多筆資料:c1 ^ c2 = p1 ^ p2,可還原明文關係
|
| 無完整性保護 | 任意修改密文,解密後對應明文位元同步翻轉,無法偵測竄改 |
| 無認證 | 無法驗證資料來源與完整性 |
| 金鑰管理困難 | 對稱金鑰分發、輪換、撤銷皆無標準機制 |
<?php
// 對稱加密:XChaCha20-Poly1305 (AEAD,同時提供機密性+完整性+認證)
$key = sodium_crypto_aead_xchacha20poly1305_ietf_keygen(); // 32 bytes
$nonce = random_bytes(SODIUM_CRYPTO_AEAD_XCHACHA20POLY1305_IETF_NPUBBYTES); // 24 bytes
$plaintext = "敏感資料";
$associatedData = "user_id=123"; // 不加密但驗證完整性
$ciphertext = sodium_crypto_aead_xchacha20poly1305_ietf_encrypt(
$plaintext, $associatedData, $nonce, $key
);
// 解密驗證
$decrypted = sodium_crypto_aead_xchacha20poly1305_ietf_decrypt(
$ciphertext, $associatedData, $nonce, $key
);
if ($decrypted === false) {
throw new Exception("解密失敗:資料已被竄改或金鑰錯誤");
}
echo $decrypted; // 敏感資料
<?php
$key = random_bytes(32); // 256-bit
$iv = random_bytes(12); // GCM 建議 96-bit nonce
$plaintext = "敏感資料";
$aad = "context_data";
$ciphertext = openssl_encrypt($plaintext, 'aes-256-gcm', $key, OPENSSL_RAW_DATA, $iv, $tag, $aad, 16);
// 儲存:$iv . $tag . $ciphertext
// 解密
$decrypted = openssl_decrypt($ciphertext, 'aes-256-gcm', $key, OPENSSL_RAW_DATA, $iv, $tag, $aad);
if ($decrypted === false) throw new Exception("解密驗證失敗");
<?php
$hash = password_hash($password, PASSWORD_DEFAULT); // 目前 bcrypt,未來自動升級
if (password_verify($input, $hash)) { /* 登入成功 */ }
if (password_needs_rehash($hash, PASSWORD_DEFAULT)) {
$newHash = password_hash($password, PASSWORD_DEFAULT);
// 更新資料庫
}
XOR 加密僅適合教學示範位元運算原理,絕不可用於任何真實敏感資料保護。現代 PHP 專案請直接使用 Sodium (libsodium) 或 OpenSSL AEAD 模式,獲得經過密碼學專家審驗的安全保障。