AES(Advanced Encryption Standard)是目前最廣泛採用的對稱加密標準。本文提供兩種 PHP 實作方案:純 PHP 實現(無擴展依賴、跨平台)與 mcrypt 擴展(效能較好、需安裝擴展),均支援 AES-256-CTR 模式。
包含兩個類別:Aes 核心演算法、AesCtr CTR 模式封裝。
<?php
require 'aes.class.php';
require 'aesctr.class.php';
// 每次加密結果不同(預設 keep=0)
$encrypted = AesCtr::encrypt('Hello World', 'secret_key', 256);
echo "Encrypt: $encrypted
";
$decrypted = AesCtr::decrypt($encrypted, 'secret_key', 256);
echo "Decrypt: $decrypted
";
// 固定 nonce 產生固定密文(keep=1,僅測試用)
$fixed = AesCtr::encrypt('Hello World', 'secret_key', 256, 1);
echo "Fixed: $fixed
";
<?php
function aes_crypt($data, $key, $mode = 'encrypt') {
if ($data === '') return '';
$iv = strrev($key); // 簡易 IV,生產環境應使用隨機 IV
$td = mcrypt_module_open('rijndael-256', '', 'ofb', '');
mcrypt_generic_init($td, $key, $iv);
$result = '';
switch ($mode) {
case 'encrypt':
$result = base64_encode(mcrypt_generic($td, $data));
break;
case 'decrypt':
$result = mdecrypt_generic($td, base64_decode($data));
break;
}
mcrypt_generic_deinit($td);
mcrypt_module_close($td);
return $result;
}
// 使用
$key = "fdipzone201314showmethemoney!@#$"; // 32 字元 = 256 bits
$plain = "show me the money";
$enc = aes_crypt($plain, $key, 'encrypt');
$dec = aes_crypt($enc, $key, 'decrypt');
echo "Enc: $enc
Dec: $dec";
| 項目 | 建議 | 風險 |
|---|---|---|
| 金鑰管理 | 使用環境變數、金鑰管理服務(KMS)、硬體安全模組(HSM) | 硬編碼金鑰極易洩露 |
| IV/Nonce | 每次加密生成隨機 IV(16 位元組),與密文一併儲存 | 固定 IV 導致相同明文產生相同密文 |
| 模式選擇 | 優先使用 GCM(認證加密)或 CBC + HMAC,CTR 需額外完整性驗證 | CTR/OFB 無完整性保護,易受位元翻轉攻擊 |
| 金鑰派生 | 使用 PBKDF2、Argon2、scrypt 從密碼派生金鑰,迭代次數 ≥ 100,000 | 直接用密碼作金鑰強度不足 |
| 擴展選擇 | PHP 7.2+ 必須改用 openssl_encrypt 或 sodium (libsodium) | mcrypt 已移除,openssl 為標準替代 |
<?php
// OpenSSL AES-256-GCM (認證加密)
function aes_gcm_encrypt($data, $key) {
$iv = random_bytes(12); // GCM 建議 12 位元組 IV
$tag = '';
$ciphertext = openssl_encrypt($data, 'aes-256-gcm', $key, OPENSSL_RAW_DATA, $iv, $tag, '', 16);
return base64_encode($iv . $tag . $ciphertext);
}
function aes_gcm_decrypt($data, $key) {
$raw = base64_decode($data);
$iv = substr($raw, 0, 12);
$tag = substr($raw, 12, 16);
$ciphertext = substr($raw, 28);
return openssl_decrypt($ciphertext, 'aes-256-gcm', $key, OPENSSL_RAW_DATA, $iv, $tag, '', 16);
}
// Sodium (libsodium) - 現代加密標準庫
function sodium_encrypt($data, $key) {
$nonce = random_bytes(SODIUM_CRYPTO_SECRETBOX_NONCEBYTES);
$ciphertext = sodium_crypto_secretbox($data, $nonce, $key);
return base64_encode($nonce . $ciphertext);
}
function sodium_decrypt($data, $key) {
$raw = base64_decode($data);
$nonce = substr($raw, 0, SODIUM_CRYPTO_SECRETBOX_NONCEBYTES);
$ciphertext = substr($raw, SODIUM_CRYPTO_SECRETBOX_NONCEBYTES);
return sodium_crypto_secretbox_open($ciphertext, $nonce, $key);
}
openssl_encrypt (AES-GCM) 或 sodium,獲得最佳效能、安全性與標準相容性。加密實作細節決定安全成敗,建議優先採用經過密碼學專家審計的標準庫(OpenSSL、libsodium),避免自行實現核心演算法。本文提供的純 PHP 版本適合學習原理與無擴展環境應急,生產環境請使用現代標準 API。