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

PHP 實作 AES-256 加密演算法:純 PHP 實現與 mcrypt 擴展兩種方案

     編輯:PHP 相關知識

AES(Advanced Encryption Standard)是目前最廣泛採用的對稱加密標準。本文提供兩種 PHP 實作方案:純 PHP 實現(無擴展依賴、跨平台)與 mcrypt 擴展(效能較好、需安裝擴展),均支援 AES-256-CTR 模式。

方案一:純 PHP 實現(Chris Veness 移植版)

包含兩個類別:Aes 核心演算法、AesCtr CTR 模式封裝。

核心特性

  • 支援 128/192/256 位元金鑰長度
  • CTR 模式(計數器模式),適合串流加密、隨機存取
  • 密碼基礎金鑰派生(PBKDF1 簡化版)
  • Nonce 包含毫秒時間戳 + 隨機數 + 秒時間戳,確保唯一性
  • Base64 輸出便於儲存傳輸

使用範例

<?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
";

方案二:mcrypt 擴展簡易封裝(PHP 7.1 已棄用,7.2 移除)

<?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_encrypt (PHP 5.3+) / sodium (PHP 7.2+)

<?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);
}

方案選擇指南

  • 舊專案維護:若已使用 mcrypt,規劃遷移至 OpenSSL 或 Sodium。
  • 無擴展環境:純 PHP 實現可作為臨時方案,但效能與安全性不如原生擴展。
  • 新專案:直接使用 openssl_encrypt (AES-GCM) 或 sodium,獲得最佳效能、安全性與標準相容性。
  • 金鑰長度:AES-256 需 32 位元組金鑰,AES-128 需 16 位元組,切勿截斷或補零湊長度。

加密實作細節決定安全成敗,建議優先採用經過密碼學專家審計的標準庫(OpenSSL、libsodium),避免自行實現核心演算法。本文提供的純 PHP 版本適合學習原理與無擴展環境應急,生產環境請使用現代標準 API。

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