HTTPSおよびSSL3_GET_SERVER_CERTIFICATE:証明書の検証に失敗し、CAはOKです


208

開発にはXAMPPを使用しています。最近、xamppのインストールを古いバージョンから1.7.3にアップグレードしました。

HTTPS対応のサイトをカールすると、次の例外が発生します

致命的なエラー:キャッチされなかった例外 'RequestCore_Exception'とメッセージ 'cURL resource:Resource id#55; cURLエラー:SSL証明書に問題があります。CA証明書に問題がないことを確認してください。詳細:エラー:14090086:SSLルーチン:SSL3_GET_SERVER_CERTIFICATE:証明書の検証に失敗しました(60) '

この問題を修正するには、PHPコードの特定のカールオプションを使用することをお勧めします。私はこれが方法であってはならないと思います。私の古いバージョンのXAMPPには何の問題もなく、新しいバージョンをインストールした後にのみ発生したためです。

私のPHPインストールでどの設定が変更されたかを理解するのに助けが必要です。Apacheなどがこの問題を修正できます。

回答:


145

curlには、受け入れられたCAのリストが含まれていましたが、CA証明書をバンドルしなくなりました。そのため、デフォルトでは、すべてのSSL証明書を検証不能として拒否します。

CAの証明書を取得して、curlを指す必要があります。詳細については、cURLSのサーバーSSL証明書に関する詳細をご覧ください。


4
アマゾンウェブサービスのphpライブラリでカールが発生しています。ライブラリコードを編集せずに修正する方法がわかりませんでした。
Josnidhin

41
次に、証明書の検証をオフにします(CURLOPT_SSL_VERIFYPEER-> false)。SSLを実行しようとしているサイトのCA証明書を追加するか、CA検証を無効にします。これらは、使用可能な2つのオプションのみです。
Marc B

78
ちょうどFYI -設定CURLOPT_SSL_VERIFYPEERfalse敗北SSLを使用する目的を。
2013年

13
@SSL の目的の半分が無効になることはありませんか?あなたはまだあなたとあなたの仲間の間のプライバシーを手に入れます:あなたはあなたの仲間の信憑性を持たないだけです。
マークフォックス

10
真正性がなければ、送信するデータを暗号化する意味は何ですか?MITMされた場合、データはとにかく危険にさらされます
hdgarrood

290

これはWindowsでかなり一般的な問題です。あなたは必要なだけのセットにcacert.pemしますcurl.cainfo

PHP 5.3.7以降、次のことができます。

  1. https://curl.haxx.se/ca/cacert.pemをダウンロードして、どこかに保存します。
  2. 更新php.ini-curl.cainfo = "PATH_TO / cacert.pem"を追加

それ以外の場合は、cURLリソースごとに以下を実行する必要があります。

curl_setopt ($ch, CURLOPT_CAINFO, "PATH_TO/cacert.pem");

2
これはOS XのXAMPPで機能しました。ローカル証明書が見つからないためにWordpressプラグインが更新されない問題を修正しました。
ジョナサンニコル2013

8
Apacheを使用してWindowsでこの問題を解決しようとしている他の誰にとっても、PHPコードにフルパス(つまり、C:\ PATH_TO \ cacert.pem)を設定する必要がありました。IISでは、相対パスは問題なく動作するように見えました。
http203 2014年

cacert.pemが同じディレクトリにある場合、curl_setopt($ ch、CURLOPT_CAINFO、dirname(FILE)。 '/cacert.pem'); 動作します
mujaffars 2014

7
WampServerを2.で使用する場合、変数を2つの別々のphp.iniファイルに追加する必要があります。stackoverflow.com/a/25706713/1101095
Nate

不可解な点は、追加のオプションを指定せずにHTTPS経由でcurl.haxx.se/ca/cacert.pemをダウンロードできることです。curl.haxx.seの証明書はcurl自体にバックアップされていますか?
qbolec 2016年

84

警告:これにより、SSLが保護するように設計されたセキュリティ問題が発生し、コードベース全体が安全でなくなります。それはすべての推奨されるプラクティスに反します。

しかし、私にとってうまくいった本当に簡単な修正は、電話することでした:

curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);

呼び出す前に:

curl_exec():

phpファイル内。

これにより、SSL証明書の検証がすべて無効になると思います。


65
...証明書の検証を無効にすることで、SSL / TLSが保護することを目的とするMITM攻撃の可能性への扉を開いたままにします。これをしないでください!
ブルーノ

12
うん。答えでこれにもっと注意を向けるべきだった。これは、重要な作業をしていない場合にのみ行ってください。私は自分でプログラムしたWebサイトにアクセスするためにlocalhostで使用しています。
Chris Dutrow、2012年

3
私から反対投票。これはコードを機能させるための汚い修正ですが、解決策ではありません。АртурКурицынが提供する回答の方がはるかに優れています。
Ilija 2013年

2
@Brunoこれは、ヘルパースクリプト、テスト、信頼できるアプリケーション、イントラネットなどに最適なソリューションです。SSLについて少し知っている人なら誰でも、証明書の検証をスキップできることを知っています。したがって、この回答に対するすべての「スマート」なコメントや「DO N'T DO THIS THIS」のようなものは単に意味がありません。
Kenyakorn Ketsombut 2015年

5
... " SSLについて少し知っている人は誰でも[...] " ...そして、SSL / TLSの基本を少しも知らずに来ているだけの人がたくさんいることに驚かれることでしょう。ここで、エラーメッセージのクイックフィックスをコピーして貼り付けます。
Bruno

53

出典:http : //ademar.name/blog/2006/04/curl-ssl-certificate-problem-v.html

Curl:SSL証明書の問題、CA証明書に問題がないことを確認してください

2006年4月7日

Curlで安全なURLを開くと、次のエラーが発生する場合があります。

SSL証明書の問題、CA証明書に問題がないことを確認してください

エラーの理由と対処方法を説明します。

エラーを取り除く最も簡単な方法は、次の2行をスクリプトに追加することです。このソリューションには、セキュリティ上のリスクがあります。

//WARNING: this would prevent curl from detecting a 'man in the middle' attack
curl_setopt ($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt ($ch, CURLOPT_SSL_VERIFYPEER, 0); 

この2つのパラメーターの機能を見てみましょう。マニュアルを引用。

CURLOPT_SSL_VERIFYHOST:1は、SSLピア証明書内の共通名の存在を確認します。2は、一般名の存在を確認し、提供されたホスト名と一致することを確認します。

CURLOPT_SSL_VERIFYPEER:CURLがピアの証明書を検証しないようにする場合はFALSE。検証する代替証明書は、CURLOPT_CAINFOオプションで指定するか、CURLOPT_CAPATHオプションで証明書ディレクトリを指定できます。CURLOPT_SSL_VERIFYPEERが無効になっている場合(デフォルトは2)、CURLOPT_SSL_VERIFYHOSTもTRUEまたはFALSEにする必要があります。CURLOPT_SSL_VERIFYHOSTを2(これはデフォルト値です)に設定すると、提示されている証明書に、リモートリソースへのアクセスに使用しているURNと一致する「共通名」があることが保証されます。これは健全なチェックですが、プログラムが騙されていないことを保証するものではありません。

「真ん中の男」を入力してください

代わりに、プログラムが別のサーバーと通信するように誤解される可能性があります。これは、DNSやARPポイズニングなどのいくつかのメカニズムによって実現できます(これは別の日の話です)。侵入者は、プログラムが予期しているのと同じ「コモン名」で証明書に自己署名することもできます。通信は引き続き暗号化されますが、あなたの秘密は詐欺師に渡されます。この種の攻撃は「中間者」と呼ばれます

「真ん中の男」を倒す

まあ、私たちに提示されている証明書が実際に良いことを確認する必要があります。これは、妥当な*信頼できる証明書と比較することで行われます。

リモートリソースがVerisignやGeoTrustなどのメインCAのいずれかによって発行された証明書で保護されている場合は、http://curl.haxx.se/docs/caextractから取得できるMozillaのCA証明書バンドルと安全に比較でき ます。 .html

cacert.pemサーバーのどこかにファイルを保存し、スクリプトで次のオプションを設定します。

curl_setopt ($ch, CURLOPT_SSL_VERIFYPEER, TRUE); 
curl_setopt ($ch, CURLOPT_CAINFO, "pathto/cacert.pem");

上記のすべての情報クレジットの場合:http : //ademar.name/blog/2006/04/curl-ssl-certificate-problem-v.html


38
単にコピーしてここに貼り付けるのではなく、情報の出典を明記し、質問に関連する特定の部分のみを引用することは、一般に礼儀正しいと見なされています。
Dan Herd 2012

1
申し訳ありませんが、私は離れていました。ええ、私はそのためにDanを使用し、投稿を更新しました
Deepak Oberoi

6
少なくともディーパックはそれを研究する努力をした。@danherdそれで、danherd、あなたは彼がどこかからコードを取ったことを見つけるために研究をしただけですか?このコードの帰属権は何でしたか?他の誰かの過ちを見つけるために時間を無駄にする代わりに、自分で誰かを助けようとします。戦わないでください、共有してください!
GTodorov

17

上記の解決策は素晴らしいですが、WampServerを使用している場合、curl.cainfo変数の設定がphp.ini機能しないことがあります。

最終的に、WampServerには2つのphp.iniファイルがあることがわかりました。

C:\wamp\bin\apache\Apachex.x.x\bin
C:\wamp\bin\php\phpx.x.xx

1つ目は、Webブラウザを通じてPHPファイルが呼び出された場合に使用され、2つ目は、コマンドラインまたはからコマンドが呼び出された場合に使用されshell_exec()ます。

TL; DR

WampServerを使用している場合は、両方のファイルにcurl.cainfo行を追加する必要があります。 php.ini


6

神聖なすべての愛のために...

私の場合、openssl.cafilePHP構成変数をPEMファイルパスに設定する必要がありました。

curl.cainfoPHPの構成での設定がまさに必要なシステムがある多くのシステムがあることは非常に本当ですが、私が作業している環境では、Debian 8(jessie)とPHPを使用するeboraas / laravel Dockerコンテナーです5.6、その変数を設定してもうまくいきませんでした。

の出力にphp -iはその特定の構成設定について何も記述されていないことに気付きましたが、には数行ありましたopensslopenssl.capathopenssl.cafileオプションの両方がありますが、2番目のものを設定するだけで、PHP経由のcurlがHTTPS URLで問題なく機能するようになりました。


ありがとうございました!curl.cainfoの設定も機能しませんでしたが、openssl.cafileの設定は機能しました。XAMPPとPHP 7.1.1を搭載したWindows 7を使用しています。
knezmilos 2017

@knezmilos openssl.cafileをどのように設定しましたか?どこでダウンロードし、どのようにアクティブ化しましたか?
Krys 2018

ええと、久しぶりですが、phpでcurl.cainfo = "C:\ xampp \ cacert \ cacert.pem"およびopenssl.cafile = "C:\ xampp \ cacert \ cacert.pem"のようなものだと思います。 ini、私はここで答えの1つからpemファイルを取得したと思います。
knezmilos

1
「すべては神聖な愛のために...」これは私のUbuntu 18.08 / Apache / Php7.2セットアップで機能しました。カール・エラーが正しいファイルを指している場合、それは最も確かにopensslsが障害である
JTG

4

連絡しようとするアプリケーションに自己署名証明書がある場合、http: //curl.haxx.se/ca/cacert.pemの通常のcacert.pem では問題が解決しないことがあります。

サービスエンドポイントのURLが確かな場合は、ブラウザからアクセスし、証明書を「X 509証明書(チェーン付き)(PEM)」形式で手動で保存します。この証明書ファイルを

curl_setopt ($ch, CURLOPT_CAINFO, "pathto/{downloaded certificate chain file}");   

4

Amazon AMI Linuxでも同じエラーが発生します。

/etc/php.d/curl.inicurl.cainfoを設定することで解決しました

https://gist.github.com/reinaldomendes/97fb2ce8a606ec813c4b

追加2018年10月

Amazon Linux v1では、このファイルを編集します

vi /etc/php.d/20-curl.ini

この行を追加するには

curl.cainfo="/etc/ssl/certs/ca-bundle.crt"

パーフェクト、ありがとう!別の答えを作成するのではなく、問題を解決するために私がしたことを正確に追加するために質問を更新しました。
Tim

3

CURLOPT_CAINFOのカールオプションを設定するときは、一重引用符を使用してください。二重引用符を使用しても、別のエラーが発生するだけです。したがって、オプションは次のようになります。

curl_setopt ($ch, CURLOPT_CAINFO, 'c:\wamp\www\mywebfolder\cacert.pem');

さらに、php.iniファイルの設定は次のように記述する必要があります(私の二重引用符に注意してください)

curl.cainfo = "C:\wamp\www\mywebfolder"

私はこれを言う行の真下にそれを置きます: extension=php_curl.dll

(整理目的でのみ、内のどこにでも置くことができますphp.ini。別のカール参照の近くに置くだけなので、キーワードカールを使用して検索すると、1つの領域で両方のカール参照を見つけることができます。)


1
php.iniが親フォルダではなくpemファイルを指すようにしたい
dejjub-AIS

2

GuzzleHttp(Macではphp + apache)を取得してwww.googleapis.comからページを取得しようとすると、ここに到達しました。

これが誰かを助けるための私の最終的な解決策です。

このエラーが発生しているドメインの証明書チェーンを確認します。私にとってはgoogleapis.comでした

openssl s_client -host www.googleapis.com -port 443

次のようなものが返されます。

Certificate chain
 0 s:/C=US/ST=California/L=Mountain View/O=Google Inc/CN=*.googleapis.com
   i:/C=US/O=Google Inc/CN=Google Internet Authority G2
 1 s:/C=US/O=Google Inc/CN=Google Internet Authority G2
   i:/C=US/O=GeoTrust Inc./CN=GeoTrust Global CA
 2 s:/C=US/O=GeoTrust Inc./CN=GeoTrust Global CA
   i:/C=US/O=Equifax/OU=Equifax Secure Certificate Authority

注:問題を修正した後、これをキャプチャしました。チェーン出力が異なる場合があるためです。

次に、phpで許可されている証明書を確認する必要があります。ページでphpinfo()を実行します。

<?php echo phpinfo();

次に、ページ出力から読み込まれた証明書ファイルを探します。

openssl.cafile  /usr/local/php5/ssl/certs/cacert.pem

これは、正しい証明書を追加して修正する必要があるファイルです。

sudo nano /usr/local/php5/ssl/certs/cacert.pem

基本的に、このファイルの最後に正しい証明書の「署名」を追加する必要があります。

それらのいくつかはここで見つけることができます。必要に応じて、チェーン内の他のユーザーをgoogle /検索する必要がある場合があります。

彼らはこのように見えます:

証明書イメージの例

注:これはイメージであるため、人々は単にstackoverflowから証明書をコピー/貼り付けしないでください

このファイルに適切な証明書を入力したら、Apacheを再起動してテストします。


0

ここでca-certificates説明するように、パッケージを再インストールするか、問題の証明書を明示的に許可することができます


-5

解決策は非常に簡単です!この行を前に置きますcurl_exec

curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);

私にとってはうまくいきます。


7
決して、これまで無効ピア検証データが輸送中に危険にさらされている場合、あなたは気にしない場合を除きます。
rdlowrey 2014年

同意した。安全なアプリが必要な場合は、ピア検証が必要です。
Braden 2014

2
「ピアの検証を無効にしないでください」デフォルトのブラウザ機能が必要でない限り。また、なぜこれがそれほど反対されているのですか?これは、短くて甘く、ポイントに対して効果的で唯一の答えです。
アダムF

@AdamF FYI、ブラウザはデフォルトでピア証明書を検証します。警告を表示してエラーを手動でバイパスするオプションのみを提供します。
Bruno
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.