首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

PHP 可逆加密函數實現:支持自定義密鑰的雙向加解密類

     編輯:PHP 綜合知識

背景與需求

MD5、SHA 等單向哈希無法還原,適用於密碼驗證;但某些場景(API Token、配置解密、URL 簽名)需要可逆加密。本文提供一個輕量、無依賴、支持自定義密鑰的加解密實現,並分析其安全特性。

核心實現(經整理優化)

<?php
class SimpleCrypt {
    /** 加密:返回 Base64 字符串,每次結果不同 */
    public static function encrypt(string $data, string $key): string {
        $key = md5($key); // 固定 32 字節密鑰
        $ivLen = 16;
        $iv = random_bytes($ivLen); // 每次隨機 IV,確保密文不同
        $cipher = 'aes-256-cbc';
        $encrypted = openssl_encrypt($data, $cipher, $key, OPENSSL_RAW_DATA, $iv);
        if ($encrypted === false) throw new Exception('Encryption failed');
        // 組合:IV + 密文 -> Base64
        return base64_encode($iv . $encrypted);
    }

    /** 解密 */
    public static function decrypt(string $encryptedData, string $key): string {
        $key = md5($key);
        $ivLen = 16;
        $cipher = 'aes-256-cbc';
        $raw = base64_decode($encryptedData, true);
        if ($raw === false) throw new Exception('Invalid Base64');
        if (strlen($raw) < $ivLen) throw new Exception('Data too short');
        $iv = substr($raw, 0, $ivLen);
        $ciphertext = substr($raw, $ivLen);
        $decrypted = openssl_decrypt($ciphertext, $cipher, $key, OPENSSL_RAW_DATA, $iv);
        if ($decrypted === false) throw new Exception('Decryption failed');
        return $decrypted;
    }
}

// === 使用示例 ===
$key = 'my_secret_key_2024';
$plain = '敏感信息:用戶ID=10086';

$encrypted = SimpleCrypt::encrypt($plain, $key);
echo "加密: $encrypted\n";

$decrypted = SimpleCrypt::decrypt($encrypted, $key);
echo "解密: $decrypted\n";
// 輸出:解密: 敏感信息:用戶ID=10086
?>

設計亮點解析

特性說明
算法AES-256-CBC,業界標準對稱加密
密鑰派生MD5 固化為 32 字節(建議生產用 PBKDF2/Argon2)
隨機 IVrandom_bytes(16) 確保同明文每次密文不同,抵抗重放/字典攻擊
數據格式IV(16字節) || 密文 -> Base64,便於存儲傳輸
錯誤處理異常拋出,避免靜默失敗

安全建議(生產環境必讀)

  1. 密鑰管理:密鑰勿硬編碼,使用環境變量、密鑰管理系統(KMS/Vault)。
  2. 密鑰派生升級:替換 md5($key) 為 hash_pbkdf2('sha256', $key, $salt, 100000, 32),鹽值隨機存儲。
  3. 完整性校驗:建議改用 aes-256-gcm(PHP 7.1+)獲得認證加密(AEAD),防篡改。
  4. 不要自行設計加密算法:原文中的 XOR 輪換屬教學示例,絕不可用於生產(易被已知明文攻擊破解)。

原文舊代碼為何不推薦

原文提供的 keyED/encrypt/decrypt 基於簡單 XOR 與隨機種子,屬於流密碼自制實現,存在嚴重缺陷:

  • 無完整性保護,密文可被篡改。
  • 隨機數生成依賴 srand(microtime()*1e6),熵極低,可預測。
  • 密鑰派生僅 MD5,無鹽、無迭代。
  • 未經安全審計,屬「自己造輪子」大忌。

結論:學習原理可參考,實際項目務必使用 OpenSSL/libsodium 等經驗證庫。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved