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

PHP OpenSSL 擴展 (php_openssl.dll) 功能詳解與應用場景

     編輯:PHP 相關知識

OpenSSL 擴展簡介

php_openssl.dll (Windows) / openssl.so (Linux) 是 PHP 內建的 OpenSSL 封裝擴展,提供 加密、解密、簽章、驗證、憑證管理、SSL/TLS 通訊 等核心密碼學功能。現代 PHP 應用 (HTTPS 客戶端、API 簽章、支付網關、JWT、加密儲存) 均高度依賴此擴展。

核心功能分類

功能領域代表函數/用途
非對稱加密 (RSA)openssl_public_encrypt, openssl_private_decrypt, openssl_private_encrypt, openssl_public_decrypt
對稱加密 (AES 等)openssl_encrypt, openssl_decrypt, openssl_get_cipher_methods
數位簽章/驗證openssl_sign, openssl_verify, OPENSSL_ALGO_SHA256
金鑰/憑證管理openssl_pkey_new, openssl_pkey_export, openssl_x509_read, openssl_csr_new
SSL/TLS 通訊stream_socket_client (ssl://), stream_context_set_option (SSL 選項)
雜湊/摘要openssl_digest, hash() (Hash 擴展)
隨機數生成openssl_random_pseudo_bytes

啟用與驗證

; php.ini (Windows)
extension=php_openssl.dll

; php.ini (Linux)
extension=openssl.so

; 驗證
php -m | grep openssl
php -r "var_dump(extension_loaded('openssl'));"
php -r "print_r(openssl_get_cipher_methods());"

實戰應用場景

1. HTTPS API 客戶端 (cURL + SSL Context)

<?php
$url = 'https://api.example.com/data';

$ctx = stream_context_create([
    'ssl' => [
        'verify_peer'      => true,
        'verify_peer_name' => true,
        'cafile'           => '/etc/ssl/certs/ca-certificates.crt',  // CA 憑證束
        'ciphers'          => 'HIGH:!aNULL:!MD5:!3DES',
    ],
    'http' => [
        'timeout' => 30,
        'header'  => "Authorization: Bearer $token\r\nAccept: application/json\r\n",
    ],
]);

$response = file_get_contents($url, false, $ctx);
// 或搭配 cURL CURLOPT_SSL_VERIFYPEER => true

2. AES-256-CBC 對稱加密儲存敏感資料

<?php
function encryptData(string $data, string $key, string $iv): string {
    // $key: 32 bytes (256-bit), $iv: 16 bytes (128-bit)
    $encrypted = openssl_encrypt($data, 'aes-256-cbc', $key, OPENSSL_RAW_DATA, $iv);
    return base64_encode($iv . $encrypted);  // IV 前綴儲存
}

function decryptData(string $encoded, string $key): string {
    $raw = base64_decode($encoded);
    $iv = substr($raw, 0, 16);
    $encrypted = substr($raw, 16);
    return openssl_decrypt($encrypted, 'aes-256-cbc', $key, OPENSSL_RAW_DATA, $iv);
}

// 使用
$key = hash('sha256', 'master-secret-key', true);  // 從主密鑰衍生
$iv = random_bytes(16);
$encrypted = encryptData('身分證字號: A123456789', $key, $iv);
$decrypted = decryptData($encrypted, $key);

3. RSA 非對稱加密/簽章 (支付、API 簽名)

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

// 公鑰加密 (傳輸機密資料)
openssl_public_encrypt($data, $encrypted, $pubKey, OPENSSL_PKCS1_OAEP_PADDING);

// 私鑰解密
openssl_private_decrypt($encrypted, $decrypted, $privKey, OPENSSL_PKCS1_OAEP_PADDING);

// 私鑰簽名 (防篡改、身份驗證)
openssl_sign($data, $signature, $privKey, OPENSSL_ALGO_SHA256);

// 公鑰驗證
$valid = openssl_verify($data, $signature, $pubKey, OPENSSL_ALGO_SHA256); // 1=通過

4. 產生自簽憑證 (開發/測試環境 HTTPS)

<?php
$dn = [
    'countryName' => 'TW',
    'stateOrProvinceName' => 'Taipei',
    'localityName' => 'Taipei',
    'organizationName' => 'MyDev',
    'commonName' => 'localhost',
    'emailAddress' => 'admin@localhost',
];

$privKey = openssl_pkey_new(['private_key_bits' => 2048, 'private_key_type' => OPENSSL_KEYTYPE_RSA]);
$csr = openssl_csr_new($dn, $privKey);
$cert = openssl_csr_sign($csr, null, $privKey, 365, ['digest_alg' => 'sha256']);

openssl_x509_export($cert, $certPem);
openssl_pkey_export($privKey, $keyPem);

file_put_contents('localhost.crt', $certPem);
file_put_contents('localhost.key', $keyPem);
// Nginx/Apache 設定 ssl_certificate, ssl_certificate_key

5. JWT Token 簽發與驗證 (RS256)

<?php
function jwtEncode(array $payload, string $privateKeyPem): string {
    $header = ['alg' => 'RS256', 'typ' => 'JWT'];
    $segments = [
        base64UrlEncode(json_encode($header)),
        base64UrlEncode(json_encode($payload)),
    ];
    $signingInput = implode('.', $segments);
    
    $privKey = openssl_pkey_get_private($privateKeyPem);
    openssl_sign($signingInput, $signature, $privKey, OPENSSL_ALGO_SHA256);
    openssl_free_key($privKey);
    
    return $signingInput . '.' . base64UrlEncode($signature);
}

function jwtDecode(string $jwt, string $publicKeyPem): ?array {
    [$headerB64, $payloadB64, $sigB64] = explode('.', $jwt);
    $signingInput = "$headerB64.$payloadB64";
    
    $pubKey = openssl_pkey_get_public($publicKeyPem);
    $valid = openssl_verify($signingInput, base64UrlDecode($sigB64), $pubKey, OPENSSL_ALGO_SHA256);
    openssl_free_key($pubKey);
    
    if ($valid !== 1) return null;
    return json_decode(base64UrlDecode($payloadB64), true);
}

function base64UrlEncode($data) { return rtrim(strtr(base64_encode($data), '+/', '-_'), '='); }
function base64UrlDecode($data) { return base64_decode(strtr($data, '-_', '+/')); }

常見加密演算法對照

類別演算法PHP 常數/字串備註
對稱AES-256-CBC'aes-256-cbc'推薦標準,需 32B 金鑰 + 16B IV
AES-256-GCM'aes-256-gcm'AEAD 認證加密,PHP 7.1+,含標籤
ChaCha20-Poly1305'chacha20-poly1305'高效能、抗時序攻擊,PHP 7.2+
非對稱RSA-2048OPENSSL_KEYTYPE_RSA, 2048 bits通用標準
RSA-40964096 bits高安全性,效能較慢
ECDSA P-256OPENSSL_KEYTYPE_EC, 'prime256v1'金鑰較小、速度快,現代標準
雜湊SHA-256OPENSSL_ALGO_SHA256簽章標準
SHA-384OPENSSL_ALGO_SHA384更強
SHA-512OPENSSL_ALGO_SHA512最強

錯誤排查與最佳實踐

  • ❌ openssl_pkey_get_private() 回傳 false → PEM 格式錯誤、密碼錯誤、檔案權限 (0600)
  • ❌ openssl_encrypt() 回傳 false → 金鑰/IV 長度不符、演算法不支援
  • ✅ 生產環境嚴禁硬編碼金鑰:使用環境變數、Vault、KMS、HSM
  • ✅ IV 每次加密必須隨機產生 (CBC 模式),不可重複使用
  • ✅ 金鑰輪換機制:定期更換加密金鑰,舊資料重新加密
  • ✅ 使用認證加密 (GCM/CCM/ChaCha20-Poly1305) 同時保證機密性與完整性
  • ✅ 檢查 openssl_error_string() 取得詳細錯誤訊息
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved