RC4 是經典的流式加密演算法,雖已知安全性弱點(不建議用於新系統),但理解其原理對維護舊系統、學習密碼學仍有價值。本文提供標準 PHP 實作。
<?php
/**
* RC4 加密/解密(對稱操作)
*
* @param string $key 加密金鑰 (1-256 位元組)
* @param string $data 明文或密文
* @return string 密文或明文
*/
function rc4(string $key, string $data): string {
if ($key === '' || $data === '') return $data;
$keyLength = strlen($key);
$dataLength = strlen($data);
// 1. 初始化 S-box (0-255)
$s = range(0, 255);
$keyBytes = [];
for ($i = 0; $i < 256; $i++) {
$keyBytes[$i] = ord($key[$i % $keyLength]);
}
// 2. KSA: Key Scheduling Algorithm (打亂 S-box)
$j = 0;
for ($i = 0; $i < 256; $i++) {
$j = ($j + $s[$i] + $keyBytes[$i]) % 256;
[$s[$i], $s[$j]] = [$s[$j], $s[$i]];
}
// 3. PRGA: Pseudo-Random Generation Algorithm (產生金鑰流並加密)
$i = $j = 0;
$result = '';
for ($k = 0; $k < $dataLength; $k++) {
$i = ($i + 1) % 256;
$j = ($j + $s[$i]) % 256;
[$s[$i], $s[$j]] = [$s[$j], $s[$i]];
$keystreamByte = $s[($s[$i] + $s[$j]) % 256];
$result .= chr(ord($data[$k]) ^ $keystreamByte);
}
return $result;
}
// 使用範例
$key = 'SecretKey123';
$plaintext = 'Hello, RC4 Encryption!';
$ciphertext = rc4($key, $plaintext);
$decrypted = rc4($key, $ciphertext); // 相同函數解密
echo "明文: $plaintext\n";
echo "密文: " . bin2hex($ciphertext) . "\n"; // 顯示十六進位
echo "解密: $decrypted\n";
echo "驗證: " . ($plaintext === $decrypted ? '成功' : '失敗') . "\n";
?>
丟棄前 N 位元組金鑰流(建議 N ≥ 768,通常 1024 或 3072)可緩解初始偏移弱點:
function rc4Drop(string $key, string $data, int $drop = 1024): string {
// ... KSA 相同 ...
// PRGA: 先丟棄 $drop 位元組
$i = $j = 0;
for ($k = 0; $k < $drop; $k++) {
$i = ($i + 1) % 256;
$j = ($j + $s[$i]) % 256;
[$s[$i], $s[$j]] = [$s[$j], $s[$i]];
}
// 正式加密
$result = '';
for ($k = 0; $k < strlen($data); $k++) {
$i = ($i + 1) % 256;
$j = ($j + $s[$i]) % 256;
[$s[$i], $s[$j]] = [$s[$j], $s[$i]];
$result .= chr(ord($data[$k]) ^ $s[($s[$i] + $s[$j]) % 256]);
}
return $result;
}
?>
| 演算法 | PHP 實作 | 用途 |
|---|---|---|
| AES-256-GCM | openssl_encrypt($data, 'aes-256-gcm', $key, OPENSSL_RAW_DATA, $iv, $tag) | 機密資料加密(推薦) |
| ChaCha20-Poly1305 | sodium_crypto_aead_chacha20poly1305_ietf_encrypt() | 高效能、抗旁路攻擊 |
| XChaCha20-Poly1305 | sodium_crypto_aead_xchacha20poly1305_ietf_encrypt() | 長隨機 Nonce 安全 |
<?php
function aesEncrypt(string $data, string $key): string {
$iv = random_bytes(12); // GCM 建議 96-bit IV
$ciphertext = openssl_encrypt($data, 'aes-256-gcm', $key, OPENSSL_RAW_DATA, $iv, $tag, '', 16);
return base64_encode($iv . $tag . $ciphertext);
}
function aesDecrypt(string $payload, string $key): ?string {
$data = base64_decode($payload);
if (strlen($data) < 12 + 16) return null;
$iv = substr($data, 0, 12);
$tag = substr($data, 12, 16);
$ciphertext = substr($data, 28);
return openssl_decrypt($ciphertext, 'aes-256-gcm', $key, OPENSSL_RAW_DATA, $iv, $tag, '', 16);
}
?>