PHPのcurlでSSL certificate problemが出る場合

/ PHP

PHPのcurlでhttps通信を行おうとしたときに

cURL error 60: SSL certificate problem: unable to get local issuer certificate (see http://curl.haxx.se/libcurl/c/libcurl-errors.html)

が出る場合。エラーメッセージはCA認証につかう証明書ファイルが取得できないと言っている。何かしらのPHPフレームワークの中でこの例外が起こった場合はきちんとハンドリングされている(おそらくCAを無視する)こともあるがエラー出力がうるさいので直したい。

  • cacert.pem(CA証明書をダウンロードする)
  • php.iniを書き換える

ことによってエラーは消える。

cacert.pemをダウンロードする

https://curl.haxx.se

(curlライブラリの公式)からDocumentation-> CA bundleといく。次のようなページになるはず。

cacert.pemのダウンロード画面

赤で囲んだ所からcacert.pemをダウンロードする。偽の直リンクから偽のcacert.pemをダウンロードしてしまった場合には当然CA認証がすり抜けられる可能性があるのでむやみに出どころ不明なcacert.pemを使用してはいけない。これはcurlの公式が置いているものでMozillaから抽出したものであると上記ページで説明されている。

php.iniの書き換える

php.iniを開いてcurl.cainfoで検索を書けると次のような所が見つかるはず。

[curl]
; A default value for the CURLOPT_CAINFO option. This is required to be an
; absolute path.
;curl.cainfo = 

このcurl.info = の部分のコメントを解除してダウンロードしたcacert.pemの絶対パスを指定する。This is required to be an absolute pathと書かれていることを見落としてはいけない。

[curl]
; A default value for the CURLOPT_CAINFO option. This is required to be an
; absolute path.
curl.cainfo = "C:/Users/USER/php/extras/curl/cacert.pem"

絶対パスはWindowsでの一例。パスに空白が含まれている場合はきちんとダブルクォートで囲んでおく。もし相対パスで書いてしまった場合は次のエラーに遭遇することになる。

cURL error 77: error setting certificate verify locations:
  CAfile: extras/curl/ca-bundle.trust.crt
  CApath: none (see http://curl.haxx.se/libcurl/c/libcurl-errors.html)

必ずコメントが教えてくれているように絶対パスで指定するように。おそらく相対パスだと偽のCAを喰ってしまうとかの問題があるのかな?(知らん)