Linux
SSL

SSL通信時発生する証明書エラーとその仕組みを理解する

More than 5 years have passed since last update.

(2014/1/30追記)

Yahoo!のWebAPIやOpenIDでも同様の事象があったようです。

かなり影響の大きい問題だったのですね。

WebAPIやOpenIDでSSLエラーが起きる現象につきまして

http://techblog.yahoo.co.jp/maintenance/4/


問題

curlでとあるhttpsスキームのAPIを叩いたら、こんなエラーが。

SSL certificate problem, verify that the CA cert is OK. Details:

error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed

後付けで分かりましたが、原因は以下でした。

RHEL5/CentOS5でGlobalSignのルート証明書が有効期限切れで大騒ぎ

http://heartbeats.jp/hbblog/2014/01/rhel5centos5globalsign.html

記事内にもある通り、取り急ぎの対応は


接続側で証明書検証をしないようにする(curlコマンドなら -k をつける)

だったりするのですが、はじめは


証明書切れた癖に検証スルー出来るってどういうこと?そもそもそんな証明書意味ないんでは

とか思ってました・・

ということで、恥を忍んでもろもろ整理してみます。


何が起こっていたのか

結論はクライアント側にインストールされているルート証明書の有効期限切れなのですが、順を追ってみます。


そもそものSSLの仕組みをざっくりと

まずSSLの仕組みを把握しておく必要がありました。

ものすごいざっくりですが、大枠は以下の流れになります。


  • もともと、各クライアント(※)には、SSL通信に備えて(認証局/CAが発行した)ルート証明書がインストールされている。


  • そのルート証明書によって、(接続先のサーバから得られる)サーバ証明書を検証し、認証局によって正当性が担保されているかどうかチェックする。


  • サーバが正当と分かれば、クライアントは共通鍵を準備、サーバへ送信し、以降はその共通鍵を用いて通信を行う。


※ここで言うクライアントとは「あるサーバに対して接続を行う主体/接続元」のこと。

つまりそれは、ブラウザだったり、サーバだったり、何でも有り得ます。

※SSLについての詳細は、以下記事が分かりやすかったです。

イケメンとラブレターで学ぶSSLの仕組み

http://blog.jnito.com/entry/2013/05/26/064803


つまり、エラーが発生するのは

SSLの流れから考えて、基本的に遭遇するのは以下2パターンだと分かります。


  • サーバ側の証明書が不正(有効期限切れorもともと認証局によって正当性が担保されていない、等)

  • クライアント側にインストールされているルート証明書が不正(有効期限切れ等)

前者が特によくあるやつですね。

スクリーンショット_2014_01_29_21_50-2.png

通常のwebユーザーとしてもちょくちょく遭遇するこれです。

ですが、今回の原因は後者でした。

RHEL5/CentOS5でGlobalSignのルート証明書が有効期限切れで大騒ぎ

http://heartbeats.jp/hbblog/2014/01/rhel5centos5globalsign.html

つまり、


(接続先サーバの正当性をチェックするための)クライアント側(となる接続元サーバ(CentOS/RedHat))のチェック用証明書

が期限切れで使えなくなってしまったということ。

こう考えると、


取り急ぎの対応として、接続先サーバの正当性チェックを止める(ことでエラーは回避できる)

というのも納得ですね(もちろん、その際は接続先が間違いなく信頼できる、という前提が必要ですが)。

はじめに問題に遭遇した時は


  • クライアント(接続元)としてのサーバ(チェックする側)

  • 接続先としてのサーバ(チェックされる側)

という二者を混同していたようです。


対策

概念としては、基本は以下の二つになります。


  • (上記の通り)接続先のチェックを止めてしまう

  • クライアント側にインストールされているルート証明書を最新にする

今回は問題の仕組みの理解/説明を残しておきたかったということで、

対策の詳細は以下記事へのポインタのみで失礼します!

[PHP][cURL] cURLでSSL(https)のCA証明書警告の回避や設定

http://mio-koduki.blogspot.jp/2012/08/php-curlsslhttpsca.html

サーバのSSL CA(認証局)証明書が古くてcurl がエラーになる件

http://d.hatena.ne.jp/hogem/20120705/1340284071