「サーバー証明書の検証」について

内容がプログラマ寄りのところはこの色で表示しています。読み飛ばしても結構です。

目次
1.まずは「サーバー証明書の検証」を知る前に
2.証明書とは
3.Doubtful Mail Checker の証明書に対する処理
4.CRL(Certificate Revocation List、証明書失効リスト)とは
5.POP3以外の場合
6.アバスト無料アンチウイルスをインストールしてある場合
7.有名どころの証明書チェーン
8.ワイルドカード証明書について
9.中間者攻撃(man-in-the-middle 攻撃)の例


1.まずは「サーバー証明書の検証」を知る前に

まずは「サーバー証明書の検証」を知る前に

APOP 認証というのはパスワードのみの暗号化です。この場合メールの内容を見る気がある人には見られてしまいます。
SSL/TLS というのは通信の全ての暗号化です。この場合メールの内容をそんなに簡単には見られません。
とりあえずどちらかを選択できるようにしました。

さて今回の本題である「サーバー証明書の検証」ですが「SSL/TLS で暗号化する」を選択しないとチェックできません。

まずは「SSL/TLS で暗号化する」をチェックした状態で「サーバー証明書の検証」のチェックは外し、「ログ」タブで「Debug」にチェックを入れて、接続して見ましょう。

以下のような出力がされます。
Debug:SSL/TLS のバージョンは TLSv1.2 です。
Debug:暗号化方式は ECDHE-RSA-AES256-GCM-SHA384 です。
Debug:bit 数は 256 です。
Debug:SSL/TLS のタイムアウトは 7200 です。
Debug:+OK @nifty pop server at conssluserg-**.nifty.com starting. . . . . .
接続に成功しました

これはサーバー(メールサーバーのこと)とクライアント(使っているパソコンのこと)で通信をして暗号化についてネゴシエートした結果です。
これだけでも結構セキュリティは高まったといえるのですが、サーバーがなりすまされているとしたらどうなるでしょう。
通信内容は筒抜けになります。このような攻撃を中間者攻撃(man-in-the-middle 攻撃)といいます。

これをチェックするのが「サーバー証明書の検証」です。

最初は OpenSSL を使って POP3 over SSL/TLS プロトコルを調べて、そのままコーディングをするもんだと思っていました。

色々と調べてみると様々な攻撃に対処するためにプロトコルはどんどん複雑になっています。
更に互換性のため TLSv1.2 ばかりでなく他のバージョンもコーディングしなければなりません。

OpenSSL にはそれに対して SSL_connect() という強力な関数があり、暗号化についてのネゴシエートを全てやってくれます。

今後 TLS のバージョンアップがあったとしても、OpenSSL のバージョンアップで済みそうです。


2.証明書とは

証明書とは以下のような感じです。前節のホスト名である「pop.nifty.com」の証明書です。

発行者発行先(所有者)及び有効期間が必ずあります。所有者の身分は発行者が保証するというものです。

上記の例では「Cybertrust」の日本支社っぽいですね。

では発行者の身分はだれが保証してくれるのでしょう。さらにその上の発行者が保証します。

「証明のパス」タブをクリックしてみましょう。

「Cybertrust Japan Public CA G3」の身分は「DigiCert Baltimore Root」さんが保証するとしています。

その上はどうなるのでしょう。際限がなくなりますね。絶対的に信頼できる発行者が必要になります。その発行者の証明書をルート証明書といいます。

実はサーバーは自分の身分を証明するために SSL/TLS 通信途中で証明書を送ってきます。まずはピア証明書(通信相手が所有者の証明書、上記の例)及び存在すればその上位の証明書を送ってきます。これらの証明書の並びを証明書チェーンといいます。

所でサーバーが検証用のルート証明書も送ってくるとしましょう。(実際送ってくる場合と送ってこない場合がありますが...)
これで検証するのでは意味がないですね。なりすましされたらルート証明書が偽装できてしまいます。

という事はクライアント(使っているパソコンのこと)に信頼できるルート証明書が無いと検証ができません。そんなものあるのでしょうか?

実は Windows には元からルート証明書が組み込まれています。「certmgr.msc」を起動してみましょう。

上図のようにツリーを開いて、その中の「Baltimore CyberTrust Root」を起動(ダブルクリック)し「証明のパス」タブを選択してみましょう。どこかで見た名前ですね。

これでなんとかホスト名である「pop.nifty.com」の身分が保証されそうです。

クライアント側でルート証明書にアクセスしなければならないという事は、ここは OpenSSL ではできません。

実はルート証明書の実態はレジストリにあります。
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\SystemCertificates\ROOT 等
a! Reg Analyzer 等で見てください

OpenSSL は Unix で開発されたという経緯があります。Unix にレジストリという概念はありません。

アクセスするには CryptoAPI という Microsoft が用意した関数を呼ばなければいけません。


3.Doubtful Mail Checker の証明書に対する処理

Doubtful Mail Checker で「サーバー証明書の検証」をチェックし1度目の接続をすると、まず送られてきた証明書の最上位発行者の名前から前節のルート証明書を検索します。見つけたルート証明書をカレントディレクトリーに「<接続名>.cer」(前前節の例では「@nifty SSL.cer」)の名前で保存します。保存すると接続を切ってしまいます。

2度目の接続をするとまず「<接続名>.cer」を読み取り、検証を行います。その場合下記のCRLの検証も行います。

1度目の接続か2度目の接続かを判定するのは、カレントディレクトリーに「<接続名>.cer」があるかどうかで判定します。

「ログ」タブの「Debug」にチェックを入れて、接続するとピア証明書「<接続名>1.cer」とその上位の証明書「<接続名>2.cer」...をカレントディレクトリーに保存してくれます。

こういう仕様になっているのは、OpenSSL でのルート証明書はファイルになっていないと指定できないからです。
SSL_CTX_load_verify_locations()等

必要なのはルート証明書1つですので、それを保存することにしました。
レジストリにあるルート証明書を全てファイルにするよりはいいと思われます。


4.CRL(Certificate Revocation List、証明書失効リスト)とは

証明書に有効期限があるという事は言いましたが、有効期限前に失効することがあります。

証明書を発行してもらうには証明機関(上記の例だと CyberTrust社 とか、CAという、キャビンアテンダントではない)に発行を頼まなければならないですが、基本的には有料になります。

所有者がこのお金を払えなくなったとか、所有者がCAとケンカ別れをして他のCAに頼むことにしたとか。

このような場合、証明機関がCRL(証明書失効リスト)に登録することになります。

証明書チェーンを検証しただけでは検証は完成しません。証明書チェーンのCRLに当該証明書が無いことを検証しなければなりません。

それはどうやったらわかるのでしょうか。

実は証明書の中にCRLの情報が載っています。

証明書の「詳細」タブを開いてフィールドの「CRL配布ポイント」を選択してみましょう。CRLのURLが書いてあるではありませんか。

これをダウンロードできるのではないかと試しに上記URLをブラウザーに指定すると見事にダウンロードできます。

ダブルクリックすると内容が出てきます。「失効リスト」タブをクリックすると以下のように出てきます。

CRL の取り扱いですが、OpenSSL がファイルをダウンロードして決まったところに保存しなければならないのに対して、 CryptoAPI はCRL配布ポイントを求めるのに CryptGetObjectUrl()、CRLを得るのに CryptRetrieveObjectByUrl()、 CRLを検証するのに CertVerifyCRLRevocation() と API が充実しています。

特に CryptRetrieveObjectByUrl() は勝手にインターネットに接続して取得してくれます。

よって CRL の検証は証明書を CryptoAPI で使える形に変換して、これらの関数を使うことにしました。

接続後の検証としては、CRL の検証以外にピア証明書が当該ホスト名を対象にしているのかどうかを検証し (ここも参考にしてください)、
最後の仕上げとして OpenSSL の SSL_get_verify_result() で検証しています。


5.POP3以外の場合

POP3 と SSL/TLS とはどういう関係になるのでしょうか?

こういった問題を出しておいて何ですが、答えは関係が無いんです。
ちょっと言い方に語弊がありますが...。

SSL/TLS は POP3 のユーザ認証をする前に暗号化のネゴシエートをします。
ユーザIDを送る前に暗号化のネゴシエーションが終わっていなければいけないので、よく考えれば当然といえば当然ですが...。
従って暗号化のネゴシエートの相手サーバーは POP3 のサーバーである必要はありません。
さらに言うとユーザIDとパスワードもいりません。

Doubtful Mail Checker を使う場合、ホスト名はIMAP4サーバー、HTTPサーバー(Webサーバー)でもいいんです。
ユーザーIDとパスワードは嘘っぱちを入れておけばいいのです。
ただポート番号はちゃんと入れておかないといけません。

代表的なポート番号を以下に示します。
POP3 over SSL/TLS:995
IMAP4 over SSL/TLS:993
HTTP over SSL/TLS(HTTPS):443

このことを使えば、前にも説明した通り Doubtful Mail Checker のデバッグ機能を使うと、相手先のサーバーの証明書を得ることができます。
特に Web サーバーに対しては興味深いでしょう。よく行く https サイトがどういう証明書チェーンを送ってくるのか試したくありませんか?
この場合ホスト名というのは https://.../ の ... になります。

Doubtful Mail Checker を使って SSL/TLS をサポートしていて自分がよく使うサーバーの証明書を調べてみませんか?


6.アバスト無料アンチウイルスをインストールしてある場合

まず今使っている@nifty のPOPサーバー pop.nifty.com がどういう証明書を送ってくるのか、面白そうだから検証してやれ!。

あ!アバストなんだ。アバストの無料アンチウイルスを使わせてもらっているんだけど、アバストは証明機関もやっているんだ!。
手広くやっているものだなあ。

じゃあYahoo のPOPサーバー pop.mail.yahoo.co.jp も見てみよう。びっくり!。このサーバーもアバストなんだ。

Gmail のPOPサーバー pop.gmail.com も見てみよう。またまたびっくり!。このサーバーもアバストなんだ。

ちょっとおかしいぞう?。本当かなあ?。じゃあアバストのインストールされていない環境で試してみよう。

ここ Hyper-V には Windows 2016 Server もインストールしているんだ。ここからやってみよう。
あ!アバストじゃないんだ!。もしかしたら OS によって証明書が異なるようにセットされているのかなあ。

じゃあアバストを入れていない Windows 10 の環境を作ってやってみよう。
ここにはテスト用の SSD があるので、これに Windows 10 をインストールできる。
あ!アバストじゃないんだ!。

ということはアバスト無料アンチウイルスをインストールするとメールのウイルスチェックのためにこんなことをやっているのかなあ。

ルート証明書はどうなっているだろう。

やはりあった!

それではアバストのインストールされていない環境ではどうだろう。
やはりなかった!

アバストをインストールすると、メールのウイルスチェックのためにルート証明書をインストールして、サーバーが送る証明書も変更してしまっているんだ。

他の無料ソフトも調べてみよう。

AVG無料アンチウイルスを調べてみよう。

あれ?!インストーラーがほとんど同じじゃないか!実行画面もほとんど同じじゃないか!


やはり、ルート証明書がインストールされている。


7.有名どころの証明書チェーン

有名どころの証明書チェーンを、アバストをインストールしていないパソコンからチェックしました。
プロトコルホスト名中間発行者ルート証明書
POP3pop.nifty.comCybertrust Japan Public CA G3Baltimore CyberTrust Root
POP3pop.mail.yahoo.co.jpCybertrust Japan Public CA G3Baltimore CyberTrust Root
POP3pop.gmail.comGTS CA 1O1GlobalSign
POP3outlook.office365.comDigiCert Cloud Services CA-1DigiCert Global Root CA
POP3pop.aol.comDigiCert SHA2 High Assurance Server CADigiCert High Assurance EV Root CA
IMAP4imap.mail.me.comApple IST CA 2 - G1/OU=Certification AuthorityGeoTrust Global CA
HTTPwww.nifty.comCybertrust Japan Public CA G3Baltimore CyberTrust Root


8.ワイルドカード証明書について

outlook.office365.com に接続したら「ピア証明書のホスト名を確認できません」というエラーが出てしまった。

ピア証明書に問題があるなら、それをデバッグモードで取得しよう。

あれ?発行先が「outlook.com」になっている。これはホスト名と違う。

ホスト名と照合するのはここ以外にもある。それを見てみよう。

何か「*」がいっぱいある。いったいこれは何なのかネットで調べてみよう。

ワイルドカード証明書っていうんだ!

「*.office365.com」に「outlook.office365.com」をマッチさせなきゃいけないんだ。

きっとホスト名(厳密にいえばドメイン名を除いたホスト名)の変更などに対応するためこういうものを用意しているんだな。

早速 Doubtful Mail Checker でもサポートしておこう!


9.中間者攻撃(man-in-the-middle 攻撃)の例

「サーバー証明書の検証」は中間者攻撃(man-in-the-middle 攻撃)に対応するためですが、ハードウエアで考えると以前見たこの図のようになります。

イントラネット内ならサーバー管理者がLANの配線を変えてしまったり、DNS(サーバー名とIPアドレスの対応表を管理するサーバー)をいじくって変えてしまうという事が考えられます。

インターネットの中では配線をいじくるという事はプロバイダーならできるのかもしれませんがよくわかりません。

さすがに作者はプロバイダーではありませんので。

ここでプロバイダーというのは、純粋にインターネット接続業者という事で考えています。
プロバイダー自体で持っているメールサーバーに関してはイントラネットと同様に容易です。
他社のメールサーバーまで中間者攻撃ができるのかよくわかりません。

またインターネットのDNSを変えることができるのかはよくわかりません。

管理者が善意であることが必須です。

ではソフトウエアとしては方法はあるのでしょうか?

実は既に例を紹介しています。アバストです。通信内容の改竄が行われています。

信頼できないソフトはインストールしないことが基本です。

セキュリティ関連のソフトを作ることは初めての経験なので OpenSSL や CryptoAPI の使い方についても、何かありましたら作者にメールをください。


戻る