本文提供三種 PHP 加密解密方案:自定義對稱加密(簡單場景)、標準 DES 算法類(相容性要求)、URL 參數 Base64 編碼傳遞(GET 請求參數保護),含完整代碼與使用範例。
/**
* 自定義加密
* @param string $str 明文
* @param string $key 密鑰
* @return string 密文
*/
function passport_encrypt($str, $key) {
srand((double)microtime() * 1000000);
$encrypt_key = md5(rand(0, 32000));
$ctr = 0;
$tmp = '';
for ($i = 0; $i < strlen($str); $i++) {
$ctr = $ctr == strlen($encrypt_key) ? 0 : $ctr;
$tmp .= $encrypt_key[$ctr] . ($str[$i] ^ $encrypt_key[$ctr++]);
}
return base64_encode(passport_key($tmp, $key));
}
/**
* 自定義解密
*/
function passport_decrypt($str, $key) {
$str = passport_key(base64_decode($str), $key);
$tmp = '';
for ($i = 0; $i < strlen($str); $i++) {
$md5 = $str[$i];
$tmp .= $str[++$i] ^ $md5;
}
return $tmp;
}
/**
* 核心密鑰混淆
*/
function passport_key($str, $encrypt_key) {
$encrypt_key = md5($encrypt_key);
$ctr = 0;
$tmp = '';
for ($i = 0; $i < strlen($str); $i++) {
$ctr = $ctr == strlen($encrypt_key) ? 0 : $ctr;
$tmp .= $str[$i] ^ $encrypt_key[$ctr++];
}
return $tmp;
}
// 使用範例
$str = '作者:www.example.com';
$key = 'secret_key_123';
$encrypt = passport_encrypt($str, $key);
$decrypt = passport_decrypt($encrypt, $key);
echo "原文: $str
密文: $encrypt
譯文: $decrypt";
/**
* DES 加密解密類 (CBC 模式,PKCS5 填充)
* 需 PHP < 7.2 或安裝 pecl/mcrypt
*/
class DES {
private $key;
private $iv;
public function __construct($key, $iv = '') {
$this->key = $key; // 8 字節
$this->iv = $iv ?: $key; // 8 字節
}
// 加密 → 大寫十六進制字串
public function encrypt($str) {
$size = mcrypt_get_block_size(MCRYPT_DES, MCRYPT_MODE_CBC);
$str = $this->pkcs5Pad($str, $size);
return strtoupper(bin2hex(mcrypt_cbc(MCRYPT_DES, $this->key, $str, MCRYPT_ENCRYPT, $this->iv)));
}
// 解密
public function decrypt($str) {
$strBin = $this->hex2bin(strtolower($str));
$str = mcrypt_cbc(MCRYPT_DES, $this->key, $strBin, MCRYPT_DECRYPT, $this->iv);
return $this->pkcs5Unpad($str);
}
private function hex2bin($hex) {
$bin = '';
for ($i = 0; $i < strlen($hex); $i += 2) {
$bin .= chr(hexdec(substr($hex, $i, 2)));
}
return $bin;
}
private function pkcs5Pad($text, $blocksize) {
$pad = $blocksize - (strlen($text) % $blocksize);
return $text . str_repeat(chr($pad), $pad);
}
private function pkcs5Unpad($text) {
$pad = ord($text[strlen($text) - 1]);
if ($pad > strlen($text)) return false;
if (strspn($text, chr($pad), strlen($text) - $pad) != $pad) return false;
return substr($text, 0, -$pad);
}
}
// 使用範例
$des = new DES('1234abcd'); // 8字節密鑰
$encrypted = $des->encrypt('12345678');
$decrypted = $des->decrypt($encrypted);
echo "$decrypted <=> $encrypted";
⚠ 重要:PHP 7.2 移除 mcrypt 擴展。現代專案請用 OpenSSL (AES) 或 Sodium (libsodium) 替代:
// 現代推薦:AES-256-CBC (OpenSSL)
function aesEncrypt($data, $key, $iv) {
return base64_encode(openssl_encrypt($data, 'AES-256-CBC', $key, OPENSSL_RAW_DATA, $iv));
}
function aesDecrypt($data, $key, $iv) {
return openssl_decrypt(base64_decode($data), 'AES-256-CBC', $key, OPENSSL_RAW_DATA, $iv);
}
// 密鑰派生建議
$key = hash('sha256', 'master_secret', true); // 32字節
$iv = random_bytes(16); // 16字節
/**
* 加密陣列參數用於 URL 傳遞
*/
function args_encode(array $data) {
$query = http_build_query($data);
return base64_encode($query);
}
/**
* 解密 URL 參數
*/
function args_decode() {
if (!isset($_GET['args'])) return [];
$query = base64_decode($_GET['args']);
parse_str($query, $params);
return $params;
}
// 使用
$params = ['user_id' => 123, 'action' => 'view', 'token' => 'abc'];
$url = 'target.php?args=' . args_encode($params);
// 產生: target.php?args=X3VzZXJfaWQ9MTIzJmFjdGlvbj12aWV3JnRva2VuPWFieA==
// 目標頁
$params = args_decode();
// $params = ['user_id'=>'123', 'action'=>'view', 'token'=>'abc']
| 場景 | 推薦算法 | PHP 版本 | 備註 |
|---|---|---|---|
| 簡單混淆、無安全合規要求 | 自定義對稱加密 | 所有版本 | 無擴展依賴、不可用於敏感數據 |
| 相容老系統 DES | DES 類 (mcrypt) | < 7.2 | 新專案禁用 |
| 現代項目敏感數據加密 | AES-256-GCM (OpenSSL) | 5.4+ | 認證加密、防篡改、性能佳 |
| 高安全、抗側信道攻擊 | XChaCha20-Poly1305 (Sodium) | 7.2+ | 現代標準、無 nonce 重用風險 |
| URL 參數防篡改/隱藏 | Base64 + 簽名/HMAC | 所有版本 | 非加密、需配合簽名驗證完整性 |