web-dev-qa-db-ja.com

curlopt_cainfoを使用したcURL証明書の検証が機能しない

API呼び出しを実行するたびにSSL証明書を検証したい。私はこのガイドに従ってきました:

http://artur.ejsmont.org/blog/content/how-to-properly-secure-remote-api-calls-from-php-application

これは私のコードです:

$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, "https://api-3t.sandbox.Paypal.com/nvp");
curl_setopt($ch, CURLOPT_POSTFIELDS, ($apiCredentials . $nvpStr));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); //Returnerar resultatet istället för att skriva ut det

curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($ch, curlopt_cainfo, (dirname(__FILE__) . '/cacert.pem'));

$response = curl_exec($ch);

問題は、SSL証明書がまったく検証されていないことです。cacert.pemファイルがチェックされていないようです。ファイルの名前を変更して削除しました。また、証明書発行者からのものであるcacert.pemファイル内のすべての証明書を削除して、ファイルを編集しようとしました。 API呼び出しは、何があっても実行されます!

問題は何でしょうか?

1
Marcus Edensky

かなりシンプル:-)

まず、スクリプトを実行すると、奇妙なエラーが発生しました。

PHP Notice:  Use of undefined constant curlopt_cainfo - assumed 'curlopt_cainfo' in ...
PHP Warning:  curl_setopt() expects parameter 2 to be long, string given in ...

だから私はcurlopt_cainfoCURLOPT_CAINFOに置き換えました-それはそれらを取り除くようです。

curl_exec()呼び出しの後に次のコードを追加しました:

if (curl_errno($ch)) {
    echo 'Curl error: ' . curl_error($ch);
}

cacert.pemを逃したか、パスが無効な場合、次のように表示されました。

Curl error: Problem with the SSL CA cert (path? access rights?)

次のようにPaypalサイトから証明書をハッキングしようとした後(--[〜#〜] not [〜#〜]これを本番環境で実行してください):

openssl s_client -connect api-3t.sandbox.Paypal.com:443 </dev/null | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > cacert.pem

再び文句を言った

Curl error: Peer certificate cannot be authenticated with known CA certificates

Mozillaから証明書バンドルを適切に提供した後:

wget http://curl.haxx.se/ca/cacert.pem -O cacert.pem 

それはうまく動作します:-)

CurlはmozillaのCURLOPT_CAINFOにバンドルされているため、cacert.pemオプションを指定する必要はないと私は思います。これは、CURLOPT_SSL_VERIFYPEERCURLOPT_SSL_VERIFYHOSTが有効になっているだけですぐに機能するはずです。

2
lukash