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

PHP 加密解密字串匯總:Discuz authcode、自定義 encrypt、OpenSSL AES/RSA

     編輯:PHP 綜合知識

專案中常需對敏感資料(Token、用戶 ID、API 參數)加密存儲或傳輸。本文匯總三種經典 PHP 加解密方案:Discuz! authcode(動態金鑰、時效性)、自定義 encrypt(簡易對稱)、現代 OpenSSL AES/RSA(標準算法),並說明適用場景與安全建議。

1. Discuz! authcode(經典、含時效驗證)

function authcode($string, $operation = 'DECODE', $key = '', $expiry = 0) {
    $ckey_length = 4;
    $key = md5($key ? $key : 'YOUR_GLOBAL_KEY');
    $keya = md5(substr($key, 0, 16));
    $keyb = md5(substr($key, 16, 16));
    $keyc = $ckey_length ? ($operation == 'DECODE' ? substr($string, 0, $ckey_length) : substr(md5(microtime()), -$ckey_length)) : '';
    $cryptkey = $keya . md5($keya . $keyc);
    $key_length = strlen($cryptkey);

    $string = $operation == 'DECODE'
        ? base64_decode(substr($string, $ckey_length))
        : sprintf('%010d', $expiry ? $expiry + time() : 0) . substr(md5($string . $keyb), 0, 16) . $string;
    $string_length = strlen($string);

    $result = '';
    $box = range(0, 255);
    $rndkey = [];
    for ($i = 0; $i <= 255; $i++) $rndkey[$i] = ord($cryptkey[$i % $key_length]);
    for ($j = $i = 0; $i < 256; $i++) {
        $j = ($j + $box[$i] + $rndkey[$i]) % 256;
        $tmp = $box[$i]; $box[$i] = $box[$j]; $box[$j] = $tmp;
    }
    for ($a = $j = $i = 0; $i < $string_length; $i++) {
        $a = ($a + 1) % 256;
        $j = ($j + $box[$a]) % 256;
        $tmp = $box[$a]; $box[$a] = $box[$j]; $box[$j] = $tmp;
        $result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256]));
    }

    if ($operation == 'DECODE') {
        if ((substr($result, 0, 10) == 0 || substr($result, 0, 10) - time() > 0) &&
            substr($result, 10, 16) == substr(md5(substr($result, 26) . $keyb), 0, 16)) {
            return substr($result, 26);
        }
        return '';
    } else {
        return $keyc . str_replace('=', '', base64_encode($result));
    }
}

特點:動態金鑰(同明文產生不同密文)、內建時間戳驗證、資料完整性校驗(keyb)。

用法:

$key = 'my_secret_key';
$enc = authcode('user_id=123', 'ENCODE', $key, 3600); // 1小時有效
$dec = authcode($enc, 'DECODE', $key); // 過期回傳空字串

2. 簡易對稱加密 encrypt(輕量、無依賴)

function encrypt($string, $operation, $key = '') {
    $key = md5($key);
    $key_length = strlen($key);
    $string = $operation == 'D' ? base64_decode($string) : substr(md5($string . $key), 0, 8) . $string;
    $string_length = strlen($string);
    $rndkey = $box = []; $result = '';
    for ($i = 0; $i <= 255; $i++) {
        $rndkey[$i] = ord($key[$i % $key_length]);
        $box[$i] = $i;
    }
    for ($j = $i = 0; $i < 256; $i++) {
        $j = ($j + $box[$i] + $rndkey[$i]) % 256;
        $tmp = $box[$i]; $box[$i] = $box[$j]; $box[$j] = $tmp;
    }
    for ($a = $j = $i = 0; $i < $string_length; $i++) {
        $a = ($a + 1) % 256;
        $j = ($j + $box[$a]) % 256;
        $tmp = $box[$a]; $box[$a] = $box[$j]; $box[$j] = $tmp;
        $result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256]));
    }
    if ($operation == 'D') {
        return (substr($result, 0, 8) == substr(md5(substr($result, 8) . $key), 0, 8)) ? substr($result, 8) : '';
    }
    return str_replace('=', '', base64_encode($result));
}

用法:encrypt($str, 'E', $key) 加密,encrypt($enc, 'D', $key) 解密。

3. 現代標準:OpenSSL AES-256-CBC / RSA(推薦生產環境)

// AES-256-CBC 對稱加密
function aesEncrypt($data, $key, $iv = '') {
    $key = hash('sha256', $key, true); // 32 bytes
    $iv = $iv ?: openssl_random_pseudo_bytes(16);
    $encrypted = openssl_encrypt($data, 'AES-256-CBC', $key, OPENSSL_RAW_DATA, $iv);
    return base64_encode($iv . $encrypted); // IV 前置存放
}

function aesDecrypt($b64, $key) {
    $key = hash('sha256', $key, true);
    $raw = base64_decode($b64);
    $iv = substr($raw, 0, 16);
    $encrypted = substr($raw, 16);
    return openssl_decrypt($encrypted, 'AES-256-CBC', $key, OPENSSL_RAW_DATA, $iv);
}

// RSA 非對稱(見文章 59832 完整版)

方案選擇指南

安全核心原則

  1. 勿自創加密算法,採用經驗證的標準庫。
  2. 金鑰管理:金鑰不硬編碼,使用環境變數、密碼管理系統(Vault、AWS KMS)。
  3. 隨機 IV:對稱加密每次加密必須使用隨機 IV。
  4. 認證加密:優先使用 AES-GCM 或 ChaCha20-Poly1305(PHP 7.1+ openssl_encrypt 支援 OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING 需手動處理 TAG)。
  5. 時序安全比對:驗證簽名/Hash 使用 hash_equals()。

根據業務敏感度選擇合適方案,並遵循金鑰管理與算法最佳實踐。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
場景推薦方案理由
內部系統、短效 Token、需時效性authcode內建過期驗證、動態密文防重放
簡單配置檔、非核心資料encrypt程式碼短、無擴展依賴
API 介接、用戶隱私資料、跨語言OpenSSL AES/RSA標準算法、經安全審計、效能佳、支援硬體加速
密碼儲存password_hash/verify專為密碼設計、自動鹽值、可調成本