簡體   English   中英

將 PHP cURL 與 SSL 證書一起使用時出錯

[英]Error using PHP cURL with SSL certificates

我正在嘗試使用 cURL 編寫一個 PHP 腳本,該腳本可以通過使用 SSL 證書的頁面以及用戶名和密碼來授權用戶,但我似乎無法通過 SSL 證書階段。

在這種情況下, curl_setopt($handle, CURLOPT_VERIFYPEER, 0)不幸的是不是一個選項。 證書是身份驗證的必需部分,否則我會收到其他類似的 SO 帖子中提到的錯誤。

我已經嘗試了一些帶有 cURL 的命令行運行:

> curl --url https://website

這將返回(60) SLL certificate problem錯誤。 如果我調整命令以包含--cacert選項:

> curl --url https://website --cacert /path/to/servercert.cer

它工作得很好; 返回 auth 網站。

但是,我嘗試了以下 PHP 代碼:

$handle = curl_init();
$options = array( 
                  CURLOPT_RETURNTRANSFER => false,
                  CURLOPT_HEADER         => true,
                  CURLOPT_FOLLOWLOCATION => false,
                  CURLOPT_SSL_VERIFYHOST => '0',
                  CURLOPT_SSL_VERIFYPEER => '1',
                  CURLOPT_CAINFO         => '/path/to/servercert.cer',
                  CURLOPT_USERAGENT      => 'Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)',
                  CURLOPT_VERBOSE        => true,
                  CURLOPT_URL            => 'https://website'
           );

curl_setopt_array($handle, $options);
curl_exec($handle);
if (curl_errno($handle)) {
  echo 'Error: ' . curl_error($handle);
}
curl_close($handle);

我原以為代碼本質上類似於 shell 命令,但我收到了以下錯誤消息:

錯誤:錯誤設置證書驗證位置:CAfile:/path/to/servercert.cer CApath:none

我已經閱讀了我能找到的所有文獻(特別是在 php.net 和 curl.haxx 上),但似乎找不到任何可以解決這個問題的東西。 有什么建議么?

我試過chmod 777 servercert.cer沒有成功。 但是,在通過php test.php從命令行而不是瀏覽器中使用上述代碼執行 PHP 腳本時,它運行良好。 為什么它在瀏覽器中不起作用的任何解釋?

因為事情是通過命令行而不是通過 php 使用 curl 工作的,所以我會追求 curl 是問題所在。

根據此 URL, http://curl.haxx.se/docs/sslcerts.html ,這是您在上面引用的 SO 帖子中的參考( 使用 CURL (php) 閱讀 SSL 頁面)...

“直到 7.18.0,curl 捆綁了一個默認安裝的嚴重過時的 ca 包文件。如今,curl 檔案根本不包含 ca 證書。您需要在其他地方獲取它們。例如,請參見下文。

如果遠程服務器使用自簽名證書,如果您未安裝 CA 證書捆綁包,如果服務器使用由 CA 簽名的證書(未包含在您使用的捆綁包中)或遠程主機是冒名頂替者冒充您最喜歡的站點,並且您想要從此服務器傳輸文件,請執行以下操作之一:”

然后繼續列出您可以嘗試的一些步驟。

由於您的 curl 7.16.3 版本早於 7.18.0,如果您還沒有,我建議您更新 curl 和 openssl 組件,然后完成上面引用的列表。

提問 6 年后,我在共享主機上遇到了同樣的問題,顯然沒有令人滿意的答案。 我為自己找到了一個解決方案,希望對大家有用。

你可以試試這個配置:

curl_setopt($config,CURLOPT_SSL_VERIFYHOST,0);
curl_setopt($config,CURLOPT_SSL_VERIFYPEER,1);
curl_setopt($config,CURLOPT_CAINFO,'ca-bundle.crt');
curl_setopt($config,CURLOPT_CAPATH,'ca-bundle.crt');

我遇到了與 @Magsol 相同的錯誤: Error: error setting certificate verify locations: CAfile: /path/to/servercert.cer CApath: none 所以我添加了第 4 行來設置 CAPath。

這是和我一起工作。 但請注意,CA 文件必須放在可訪問的目錄中(使用 chmod 755 或 777),如果 CA 文件與 PHP 文件在同一目錄中會更好。

對此進行闡述和總結:

如果您有一個使用 PHP curl 的 PHP 文件並將系統的 ca 證書放在同一目錄中,則以下代碼將為您提供快速入門

    $url = "https://myserver.mydomain.local/get_somedata.php";
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);

//These next lines are for the magic "good cert confirmation"
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
    curl_setopt($ch, CURLOPT_VERBOSE, true);

//for local domains:
//you need to get the pem cert file for the root ca or intermediate CA that you signed all the domain certificates with so that PHP curl can use it...sorry batteries not included
//place the pem or crt ca certificate file in the same directory as the php file for this code to work
    curl_setopt($ch, CURLOPT_CAINFO, __DIR__.'/cafile.pem');
    curl_setopt($ch, CURLOPT_CAPATH, __DIR__.'/cafile.pem');

//DEBUG: remove slashes on the next line to prove "SSL verify" is the cause       
//curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);

    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

//Error handling and return result
    $data = curl_exec($ch);
    if ($data === false) {
        $result = curl_error($ch);
    } else {
        $result = $data;
    }

// Close handle
    curl_close($ch);
    return $result;

現在這個問題已經很老了,但可能對一些目前正在尋找答案的用戶有用。

我有一個關於帶有 SSL 的 API 的類似問題,CURL 有問題(不是瀏覽器)我的問題是我只放置了證書而不是證書鏈/捆綁包。 然后我把它放進去,事情就開始起作用了。 所以這對於避免問題很重要。

希望這對某人有用。

如果它適合你,你可以試試這個:

curl_setopt($ch, CURLOPT_URL, "https://test.example.com/v1/authenticate.json?api_key=123456");
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,0);
curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_FAILONERROR, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch,CURLOPT_CAINFO,'cert.embedapp.20191004.pem');
curl_setopt($ch,CURLOPT_CAPATH,'./cert.embedapp.20191004.pem');

注釋這些行並添加以下內容:

//curl_setopt($ch,CURLOPT_CAINFO,'cert.embedapp.20191004.pem');
//curl_setopt($ch,CURLOPT_CAPATH,'./cert.embedapp.20191004.pem');
curl_setopt($ch, CURLOPT_SSLCERT,'cert.embedapp.20191004.pem');

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM