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

PHP OpenSSL 加解密函數速查與 RSA 實戰範例

     編輯:PHP 相關知識

PHP OpenSSL 加解密函數速查與 RSA 實戰範例

PHP openssl 擴展提供完整的非對稱加密、簽名驗證、對稱加密、摘要雜湊功能。本文整理核心函數速查表,並提供 RSA 金鑰生成、加解密、簽名驗證的完整可執行範例。

核心非對稱加密函數

函數用途關鍵參數
openssl_public_encrypt()公鑰加密 (資料機密性)$data, &$crypted, $pubKey, $padding=OPENSSL_PKCS1_PADDING
openssl_public_decrypt()公鑰解密 (驗證私鑰加密簽名)$data, &$decrypted, $pubKey, $padding
openssl_private_encrypt()私鑰加密 (數位簽名)$data, &$crypted, $privKey, $padding
openssl_private_decrypt()私鑰解密 (公鑰加密資料解密)$data, &$decrypted, $privKey, $padding

簽名與驗證函數

函數用途
openssl_sign()私鑰簽名,回傳二進位簽名
openssl_verify()公鑰驗證簽名,回傳 1/0/-1
openssl_digest()計算摘要 (SHA256, SHA512, MD5...)

金鑰管理函數

  • openssl_pkey_new() / openssl_pkey_export() / openssl_pkey_get_details() / openssl_pkey_free()
  • openssl_pkey_get_public() / openssl_pkey_get_private():從 PEM 字串/檔案載入資源

OpenSSL CLI 生成 RSA 金鑰對 (2048 位元)

# 1. 生成帶密碼保護的私鑰
openssl genrsa -des3 -out private.pem 2048

# 2. 移除密碼 (方便程式讀取,生產環境建議保留密碼)
openssl rsa -in private.pem -out private_nopass.pem

# 3. 從私鑰導出公鑰
openssl rsa -in private_nopass.pem -pubout -out public.pem

PHP 完整 RSA 加解密與簽名範例

<?php
// 載入金鑰
$privKey = openssl_pkey_get_private(file_get_contents('private_nopass.pem'));
$pubKey  = openssl_pkey_get_public(file_get_contents('public.pem'));

$data = '敏感資料:身分證 A123456789、金額 10000';

// --- 公鑰加密 / 私鑰解密 (資料機密性) ---
openssl_public_encrypt($data, $encrypted, $pubKey, OPENSSL_PKCS1_OAEP_PADDING); // 建議 OAEP
echo "加密後 (Base64): " . base64_encode($encrypted) . "\n";

openssl_private_decrypt($encrypted, $decrypted, $privKey, OPENSSL_PKCS1_OAEP_PADDING);
echo "解密後: $decrypted\n";
assert($decrypted === $data);

// --- 私鑰簽名 / 公鑰驗證 (完整性、不可否認性) ---
openssl_sign($data, $signature, $privKey, OPENSSL_ALGO_SHA256);
echo "簽名: " . base64_encode($signature) . "\n";

$verify = openssl_verify($data, $signature, $pubKey, OPENSSL_ALGO_SHA256);
echo "驗證結果: " . ($verify === 1 ? '成功' : ($verify === 0 ? '失敗' : '錯誤')) . "\n";

// 釋放資源
openssl_free_key($privKey);
openssl_free_key($pubKey);
?>

實戰場景:API 介面簽名驗證流程

  1. 客戶端:將請求參數按鍵名排序拼接 → 私鑰簽名 → Base64 → 放入 Header X-Signature
  2. 伺服端:取 Header 簽名、原始參數 → 公鑰驗證 → 通過才處理業務
  3. 防重放:請求含 timestamp + nonce,伺服端檢查時間窗 (±5min) + Redis 去重 nonce

常見坑位與最佳實踐

問題解決
資料長度超過金鑰長度 (RSA-2048 最大加密 245 字節)採用混合加密:隨機生成 AES-256 金鑰加密資料,RSA 僅加密 AES 金鑰
PKCS#1 v1.5 填充遭 Bleichenbacher 攻擊強制使用 OPENSSL_PKCS1_OAEP_PADDING (PHP 5.4+)
私鑰檔案洩露生產環境私鑰加密儲存 (HSM、KMS、環境變數加密),程式啟動時解密載入
跨語言互通 (Java, Go, Python)統一使用 PKCS#8 格式私鑰、X.509 公鑰、Base64 編碼、OAEP+SHA256
效能瓶頸RSA 僅用於金鑰交換/簽名,大量資料改用 AES-GCM/ChaCha20-Poly1305

對稱加密補充 (AES-256-GCM)

$key = random_bytes(32);           // 256-bit 金鑰
$iv  = random_bytes(12);           // GCM 建議 96-bit IV
$tag = '';
$ciphertext = openssl_encrypt($data, 'aes-256-gcm', $key, OPENSSL_RAW_DATA, $iv, $tag, '', 16);
// 傳輸: $iv . $ciphertext . $tag (Base64)
// 解密: openssl_decrypt(..., $iv, $tag)

掌握 OpenSSL 核心函數、金鑰格式、填充模式與混合加密架構,即可構建符合現代密碼學最佳實踐的 PHP 安全系統。

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