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

PHP 介面資料加解密與簽名驗證:phpseclib 實戰完整指南

     編輯:PHP 相關知識

現代 API 介面常需「資料加密傳輸」與「簽名驗證防篡改」。PHP 原生 OpenSSL 操作繁瑣,phpseclib 提供純 PHP 實現的 AES、RSA、大整數運算,無需擴充套件,相容性極佳。本文示範完整流程:AES-ECB 解密資料 → RSA-PKCS1 驗證簽名 → RSA 加解密示範。

環境準備

composer require phpseclib/phpseclib:~3.0

完整實作範例

<?php
require_once 'vendor/autoload.php';

use phpseclib\Crypt\AES;
use phpseclib\Crypt\RSA;

// ========== 1. 參數設定(實際專案請從安全儲存讀取) ==========
// Base64 編碼的 AES 金鑰(16/24/32 位元組對應 128/192/256 bits)
$aesKeyB64 = 'qZe60QZFxuirub2ey4+7+Q==';
$aesKey = base64_decode($aesKeyB64);

// Base64 編碼的 RSA 公鑰(PKCS#1 或 PKCS#8 格式)
$publicKeyB64 = 'MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCffOeIVYut9jW5w1L5uKX4aDvd837a8JhaWm5S8YqNQfgEmfD9T+rDknXLqMT+DXeQAqGo4hBmcbej1aoMzn6hIJHk3/TfTAToNN8fgwDotHewsTCBbVkQWtDTby3GouWToVsRi1i/A0Vfb0+xM8MnF46DdhhrnZrycERBSbyrcwIDAQAB';
$publicKey = base64_decode($publicKeyB64);

// 接收到的加密資料(Base64)
$cryptTextB64 = 'v66YKULHFld2JElhm/J9qik2Edr1JHdZIc/k/OesU2GbTX2usXyvF4jGvzvoihrrE8FsfKmllmjsMIjO5fdrS/FD20bYFii4JW3BO3bzshXmz6AEs2DWwG4sK9mNojfOC0IsMoV311X5/JlgUoQXkDy4F5HHpYE9d/xGb0g2XE/hnGSSy2cpQcvQtBlBmixwSckNhsEG92lovlOz8ULwkqG5o7x+qB7P/EMII/WaFAXBJXDXvZX7lmGcOgon6wLhKJLGXorP6BIxOg6LGc6Ux7BAt3i9+0lujNgxIq/sDsl23hsr3yOUpV5C5a813nrHx4HJyd/hBT1UvIUml+eTmJwWCpSfs2cvxIUr0CE57JAZVyXjK13shK3IsZHLPPsm/JcDCrdy0Co/d5uIGJAdzXdsQ56xsju+tlvnA1J6yq2tDIfYK/x6k911A5WXLKYxztD1nq+bTYN3Gv/WFfrzVtgWQBrh06ihS2cwvna0S9EV/YPmhnAjJmrX4trNr9NXQ9xaZaW4lGRg87U5QDV+nQjj1THk0XHFc69N9g2+DsAGyEs9tK6U0ZQ72hJZqZhBCDH1UKw0PLyIhJdxpgPPOWGp8/QVVU2julTeKunvgAAEc3n+GoZfqjsCDi1S6T2MTnjWYWNoFRBhvEZFD/revgpasTOzDQa5NqR1B+mUF70r6uw6MWLJ7cT9Tz3jq+CA';
$cryptText = base64_decode($cryptTextB64);

// 接收到的簽名(Base64)
$signatureB64 = 'XHin4uUFqrKDEhKBD/hQisXLFFSxM6EZCvCPqnWCQJq3uEp3ayxmFuUgVE0Xoh4AIWjIIsOWdnaToL1bXvAFKwjCtXnkaRwUpvWrk+Q0eqwsoAdywsVQDEceG5stas1CkPtrznAIW2eBGXCWspOj+aumEAcPyYDxLhDN646Krzw=';
$signature = base64_decode($signatureB64);

// ========== 2. AES-ECB 解密 ==========
$aes = new AES(AES::MODE_ECB);
$aes->setKey($aesKey);
$plainText = $aes->decrypt($cryptText);

echo "解密後明文:\n$plainText\n
"; // ========== 3. RSA-PKCS1 驗證簽名 ========== $rsa = new RSA(); $rsa->setSignatureMode(RSA::SIGNATURE_PKCS1); // 或 SIGNATURE_PSS(更安全) $rsa->loadKey($publicKey); // 載入公鑰 $verified = $rsa->verify($plainText, $signature); echo "簽名驗證:" . ($verified ? '✅ 通過' : '❌ 失敗') . "\n
"; // ========== 4. RSA 加解密示範(生成新鑰對) ========== $keys = $rsa->createKey(2048); // 產生 2048-bit 鑰對 $privateKey = $keys['privatekey']; $publicKeyNew = $keys['publickey']; // 使用私鑰加密(通常用於小資料加密或金鑰交換) $rsa->loadKey($privateKey); $cipherText = $rsa->encrypt($plainText); echo "RSA 私鑰加密結果(Base64):\n" . base64_encode($cipherText) . "\n
"; // 使用公鑰解密 $rsa->loadKey($publicKeyNew); $decrypted = $rsa->decrypt($cipherText); echo "RSA 公鑰解密還原:\n$decrypted\n"; ?>

關鍵類別與模式對照

類別常用模式常數說明
AESMODE_ECB, MODE_CBC, MODE_CTR, MODE_GCMECB 不需 IV 但不安全(相同明文產生相同密文),生產環境強制使用 CBC/GCM 並搭配隨機 IV
RSASIGNATURE_PKCS1, SIGNATURE_PSSPSS 比 PKCS1 更安全,建議新專案用 PSS。加密模式:ENCRYPTION_PKCS1, ENCRYPTION_OAEP(OAEP 更安全)

安全性關鍵點(必讀)

  1. 不要用 ECB 模式:範例為示範兼容舊系統。新系統請用 MODE_CBC + 隨機 IV(AES::generateIV()),IV 需與密文一起傳輸(通常前綴在密文前)。
  2. 金鑰管理:AES 金鑰、RSA 私鑰絕不可硬編碼在程式碼。應使用環境變數、HashiCorp Vault、AWS KMS、Azure Key Vault 等密鑰管理系統。
  3. 簽名演算法升級:改用 RSA::SIGNATURE_PSS + SHA256($rsa->setHash('sha256'))。
  4. 4. 加密資料完整性:單純加密無法防篡改,必須搭配簽名(簽名加密或加密再簽名),或使用 AEAD 模式(AES-GCM、ChaCha20-Poly1305)同時提供機密性與完整性。 5. RSA 加密長度限制:RSA 只能加密小於金鑰長度的資料(2048-bit 約 245 bytes)。大資料請用「混合加密」:隨機產生 AES 金鑰加密資料,再用 RSA 加密 AES 金鑰。 6. 時序攻擊防護:驗證簽名/比對 MAC 時使用 hash_equals() 或 phpseclib 內建的恆時比較。

現代替代:PHP 內建 OpenSSL 函數(PHP 7.1+)

<?php
// AES-256-GCM(推薦)
$key = random_bytes(32);
$iv = random_bytes(12); // GCM 建議 96-bit IV
$ciphertext = openssl_encrypt($plaintext, 'aes-256-gcm', $key, OPENSSL_RAW_DATA, $iv, $tag);
// 儲存:$iv . $ciphertext . $tag

// 解密
$plaintext = openssl_decrypt($ciphertext, 'aes-256-gcm', $key, OPENSSL_RAW_DATA, $iv, $tag);

// RSA 簽名驗證(PSS + SHA256)
openssl_sign($data, $signature, $privateKey, 'sha256WithRSAEncryption'); // 需開啟 OPENSSL_ALGO_SHA256
$ok = openssl_verify($data, $signature, $publicKey, 'sha256WithRSAEncryption');
?>

phpseclib 在無法安裝擴充套件的共享主機環境極有價值;若掌控伺服器環境,優先使用內建 OpenSSL,效能更好、經過更嚴格審計。

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