使用 cURL 存取 HTTPS 網址時,常遇到 SSL certificate problem: verify that the CA cert is OK 錯誤。本文提供兩種解決方案,並說明各自優缺點與適用場景。
cURL 預設驗證伺服器 SSL 憑證,需本機擁有可信任的 CA 憑證包(cacert.pem)。若系統內建憑證過期、缺失,或目標站點使用自簽憑證,驗證即會失敗。
$ch = curl_init($url); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 不驗證憑證 curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); // 不驗證域名匹配 // ... 其他選項 $response = curl_exec($ch);
cacert.pem:https://curl.se/ca/cacert.pem/etc/ssl/certs/cacert.pem 或專案目錄)。$ch = curl_init($url); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true); // 必須驗證 curl_setopt($ch, CURLOPT_CAINFO, __DIR__ . '/cacert.pem'); // 指定 CA 檔案 // 若需驗證域名(預設 2),可保持預設或顯式設定 curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2); $response = curl_exec($ch);
| 現象 | 可能原因 | 解決 |
|---|---|---|
| 仍報錯 | cacert.pem 路徑錯誤/無權限 | 用 realpath() 確認絕對路徑,檢查 open_basedir |
| 自簽憑證 | 目標站點非公信 CA 簽發 | 將自簽 CA 追加至 cacert.pem,或方案一(僅測試) |
| 憑證過期 | 目標站點憑證已過期 | 聯繫站點更新,或暫時方案一 |
| 主機名不符 | IP 直接存取、CDN 域名不匹配 | 檢查 CURLOPT_SSL_VERIFYHOST=2,確認 SNI 支援 |
$ctx = stream_context_create([
'ssl' => [
'verify_peer' => true,
'verify_peer_name' => true,
'cafile' => __DIR__ . '/cacert.pem',
]
]);
$content = file_get_contents('https://example.com', false, $ctx);
CURLOPT_SSL_VERIFYPEER=true)。ca-certificates 套件,自動維護憑證。正確配置 SSL 驗證,是保障資料傳輸機密性與完整性的基石。