「証明書エラーが出ました」。この一言から、情シスの調査が始まります。でも、エラーの理由は、期限切れ、名前の違い、中間証明書の不足、信頼されないルートなど、いくつもあります。理由を切り分けるには、ブラウザが、何を、どの順番で確かめているのかを、証明書検証の流れとして知っておくのが近道です。
シリーズ「TLS証明書の基礎」の第3回は、ブラウザによる証明書検証の流れを整理します。第1回、第2回で出てきた、サーバー証明書、中間証明書、ルート証明書が、実際の通信の中で、どう使われるのかを見ていきます。
証明書検証の結論:ブラウザは「5つのこと」を確かめている
先に結論です。ブラウザは、サイトに接続するとき、証明書について、次の5つを確かめています。
| 確認 | 見ること | 失敗の原因の例 |
|---|---|---|
| 1. 名前 | 接続先の名前が、証明書に書かれているか | 別のドメインの証明書を、設定している |
| 2. 期限 | 有効期間に入っているか | 更新を忘れて、期限切れ |
| 3. 署名・チェーン | 署名が正しく、ルートまでつながるか | 中間証明書を、サーバーに設定していない |
| 4. 信頼 | たどり着いたルートが、信頼ストアにあるか | 自己署名証明書、社内CAのルートが未登録 |
| 5. 失効 | 証明書が、取り消されていないか | 秘密鍵の漏えいなどで、失効された |
証明書検証の流れ:接続からチェーンの確認まで
TLSで接続するときの流れを、図にしました。

流れを、順に言葉にします。
- ブラウザが、サーバーに接続します。 このとき、「example.com に接続したい」という、サイトの名前も伝えます。
- サーバーが、証明書チェーンを送ります。 中身は、サーバー証明書と、中間CA証明書です。ルート証明書は、ふつう送りません。ブラウザが、すでに持っているからです。
- ブラウザが、5つの確認をします。 1つでも失敗すると、警告が出ます。
- 確認に成功すると、暗号化の鍵を決めて、通信を始めます。 画面には、鍵のマークが出ます。
ポイントは、2番の「サーバーが中間CA証明書も送る」ところです。サーバーに、サーバー証明書だけを設定して、中間CA証明書を設定し忘れると、ブラウザは、ルートまで、たどれなくなります。
失効の確認:証明書は、期限の前でも取り消される
5番の失効は、あまり意識されませんが、大事な確認です。証明書は、有効期限の前でも、取り消されることがあります。たとえば、秘密鍵が漏れた、発行の手続きに間違いがあった、などの場合です。
取り消された証明書の一覧を、失効情報といいます。ブラウザやOSは、さまざまな方法で、これを確かめます。
| 方法 | 内容 |
|---|---|
| CRL(失効リスト) | 取り消された証明書の一覧を、認証局が公開する |
| OCSP | 特定の証明書が失効しているかを、認証局に問い合わせる |
| ブラウザ独自の失効リスト | ブラウザやOSの更新で、失効情報をまとめて配る |
ここで大事なのは、失効の情報が、すべてのソフトに、同じように届くわけではないことです。ブラウザは、更新で、素早く対応できます。一方、更新されていないアプリや機器は、失効した証明書を、そのまま信頼してしまうことがあります。第4回の事件の話で、この点が出てきます。
証明書検証をコマンドで確かめる:OpenSSLで見る
ブラウザの動きは、コマンドでも再現できます。OpenSSLの s_client で、検証の結果を見られます。
# 検証の結果と、名前の確認を表示する
echo | openssl s_client -connect gadgetzine.blog:443 -servername gadgetzine.blog -verify_hostname gadgetzine.blog 2>&1 | grep -E "Verify return code|Verified peername"
このブログで実行した結果(2026年10月30日に確認)です。
Verified peername: gadgetzine.blog
Verify return code: 0 (ok)
Verified peername は、名前の確認に成功した、という意味です。Verify return code: 0 (ok) は、チェーンの検証に、成功した、という意味です。
期限は、-checkend で確かめられます。指定した秒数のあいだに、期限が来るかを調べます。
# 30日(2,592,000秒)以内に、期限が切れるか確認する
echo | openssl s_client -connect gadgetzine.blog:443 -servername gadgetzine.blog 2>/dev/null | openssl x509 -noout -checkend 2592000
「Certificate will not expire」と出れば、30日以内には、切れません。「Certificate will expire」と出たら、更新の準備を始める合図です。
証明書エラーの原因を切り分ける:テスト用サイトで見る
エラーの原因ごとに、どんな結果になるかを、テスト用のサイト(badssl.com)で試してみました。結果は、次のとおりです(2026年10月30日に確認)。
| 状況 | OpenSSLの結果 | 原因 |
|---|---|---|
| 期限切れ(expired.badssl.com) | 10 (certificate has expired) |
有効期限が切れている |
| 自己署名(self-signed.badssl.com) | 18 (self-signed certificate) |
認証局ではなく、自分で署名している |
| 信頼されないルート(untrusted-root.badssl.com) | 19 (self-signed certificate in certificate chain) |
チェーンの終点が、信頼ストアにない |
| 中間証明書の不足(incomplete-chain.badssl.com) | 21 (unable to verify the first certificate) |
サーバーが、中間CA証明書を送っていない |
ブラウザでは、同じ原因が、NET::ERR_CERT_DATE_INVALID(期限)、NET::ERR_CERT_AUTHORITY_INVALID(信頼できない発行者)、NET::ERR_CERT_COMMON_NAME_INVALID(名前の不一致)のような、エラーコードで表示されます。画面のコードと、上の表を、見比べると、原因の見当がつきます。
あるある:警告を「詳細設定 → 進む」で、通してしまう
証明書の警告が出たとき、「詳細設定 → 進む」を押して、通してしまうことがあります。開発中の自分のサーバーなら、まだよいのですが、本番のサイトや、外部のサービスで、同じことをするのは危険です。警告は、「相手が本物か、確かめられません」という意味だからです。
ごはんにたとえるなら、賞味期限が切れているお弁当に、「たぶん大丈夫」と、手を出すようなものです。原因を、切り分けてから、判断する。この回の表が、切り分けの出発点になります。
今回のまとめと次回予告
| 項目 | 内容 |
|---|---|
| 確認する5つ | 名前・期限・署名とチェーン・信頼・失効 |
| サーバーが送るもの | サーバー証明書と中間CA証明書(ルートは、ふつう送らない) |
| 失効 | 方法はいくつかあり、すべてのソフトに、同じように届くとは限らない |
| コマンド | openssl s_client で、検証の結果、名前、期限を確かめられる |
次回は、これまでの基礎の応用編です。最近話題になった、eMudhra の中間CAの鍵の問題を題材に、「中間CAの鍵が漏れると、何が困るのか」と、自分たちの環境で確かめることを、1本にまとめます。
→ 第4回:中間CAの鍵が漏れると何が起きる?eMudhraの事件と備え
ほかのセキュリティの話題は、当ブログの技術ネタからどうぞ。
参考

ITもごはんも、腹八分目が長続きのコツ!


コメント