その通信、漏れていませんか?
안녕하신게라!パナソニック コネクト株式会社クラウドソリューション部の加賀です。
前回「NTPの基本の"キ"」で「すべてのシステムは正しい時間の上に成り立っている」という話をしました。時計がズレていると、ログ順序が狂うだけでなく、今回の「証明書」の有効期限チェックもできず、通信が成立しません。
時計が正確になったところで、次に直面するのが「通信相手は本当に本物か?」「誰かに通信を覗き見(または改ざん)されていないか?」という基本的な問題です。
裏側の仕組み、利用者側での見分け方、提供者側での運用をそれぞれ見ていきます。今回は「SSL/TLSと証明書」の基本の"キ"です。
そもそも何が危ないのか
HTTPやメール送受信で利用する通信は、ネットワーク上では「ただの平文(プレーンテキスト)」です。途中の経路(ルータやプロバイダの設備など)でパケットキャプチャを使えば簡単に中身を見られてしまいます。ハガキに暗証番号を書いて送るようなものです。
何も対策しなければ、通信内容を第三者に読まれる(盗聴)、途中で書き換えられる(改ざん)、偽のサーバに接続させられる(なりすまし)という3つの脅威にさらされます。SSL/TLSはこの3つをまとめて引き受けるプロトコルで、盗聴には暗号化、改ざんには完全性検証の仕組み(TLS 1.2以前はMAC、TLS 1.3ではAEADに統合)、なりすましにはデジタル証明書で、それぞれ対処します。
「そもそもSSLとTLSって何が違うの?」と思った方もいるかもしれません。「SSL(Secure Sockets Layer)」は1990年代にNetscape社が開発した初期のプロトコルで、SSL 3.0を最後に使用禁止となっています。現在は後継の「TLS(Transport Layer Security)」です。SSL証明書やSSL通信という呼称は慣習的なもので、実態はTLS通信です。本記事でも慣例に従い「SSL/TLS」と表記します。
| プロトコル | 状態 |
|---|---|
| SSL 2.0 / 3.0 | 使用禁止(深刻な脆弱性あり、RFC 6176, 7568) |
| TLS 1.0 / 1.1 | 非推奨(2020年〜主要ブラウザで無効化済、2021年 RFC 8996) |
| TLS 1.2 | 現行(TLS 1.3への移行推奨) |
| TLS 1.3 | 現行標準(2018年 RFC 8446) |
「安全な通信」を見分けるポイント
利用者がブラウジングで気を付けられることは、実はそう多くありません。ただ、少ないからこそ押さえておきたいところです。
URLが https:// で始まっているか
最も基本的なチェックポイントです。http:// は平文通信、https:// はTLSで暗号化された通信です。ログインページやクレジットカード入力画面が http:// であれば、そのサイトは使わないのが無難です。
ブラウザのセキュリティ表示を確認する
ブラウザのアドレスバーには通信状態を示すアイコンが表示されます(かつては南京錠マークでしたが、Chrome 117以降ではチューンアイコンに変更されています)。このアイコンをクリックすると証明書の詳細が確認できます。
「証明書」には発行先のドメイン名、発行元の認証局(CA)、有効期限などが記載されています。ここで確認できるのが証明書の種類(検証レベル)です。
| 種類 | 検証内容 | 信頼度の目安 |
|---|---|---|
| DV(Domain Validation) | ドメインの所有権のみ | 最低限の暗号化は保証 |
| OV(Organization Validation) | 組織の実在確認 | 企業サイトで一般的 |
| EV(Extended Validation) | 厳格な組織審査 | 金融機関やECサイト向け |
DV証明書は「このドメインの所有者が申請した」という事実しか保証しません。フィッシングサイトでもDV証明書は取得できるので、HTTPSアイコンが出ているから安全とは言い切れない点は頭の片隅に入れておいてください。
【Tips】DV/OV/EVの見分け方
ブラウザのアドレスバーだけでは判別できません。かつてはEV証明書だとアドレスバーが緑色になり組織名が表示されていましたが、Chrome 77(2019年)やFirefox 70で廃止され、現在はどの種類でも見た目は同じです。
確認するにはアドレスバーのアイコンをクリックし、「証明書を表示」から詳細を開きます。「サブジェクト」欄に O(Organization)フィールドがあればOVかEV、なければDV。EVの場合はさらに SERIALNUMBER や BUSINESSCATEGORY といったフィールドが含まれています。ここまで確認するケースは稀ですが、こういう雑学が役立ったりするものです。
ドメイン名をよく見る
HTTPSかどうか以前に、そもそもアクセス先のドメイン名が本物かどうかも確認すべきポイントです。攻撃者は本物そっくりのドメインを取得してフィッシングサイトを立てます。たとえば amazon.co.jp に対して arnazon.co.jp(rnがmに見える)、qiita.com に対して qiitа.com(aがキリル文字のа)といった具合です。後者のようにUnicodeの見た目が似た文字を使う手口はホモグラフ攻撃と呼ばれ、アドレスバーを目視しても判別が難しいことがあります。
メールやSNSのリンクからアクセスする場合は特に注意が必要です。リンクの表示テキストとhref先が違うのは常套手段なので、重要なサービスにはブックマークか手入力でアクセスする癖をつけておくと被害を避けやすくなります。詐欺電話には掛け直すのが一番の対策であるように。
フリーWi-Fiでの注意
カフェや空港のフリーWi-Fiでは、攻撃者が偽のアクセスポイントを設置し、通信を傍受する「中間者攻撃」のリスクがあります。HTTPSで接続していればデータ自体は暗号化されていますが、偽のログインページ(HTTPのキャプティブポータルなど)に誘導される可能性もあります。機密性の高い操作(ネットバンキングなど)はフリーWi-Fiではやめておきましょう。どうしても必要ならVPNを併用してください。
ただ、そもそもなぜHTTPSだと安全と言えるのか。裏側の仕組みをもう少し覗いてみます。
暗号化の「2つの方式」
SSL/TLSの暗号化には大きく2つの方式があり、それぞれに弱点があります。
共通鍵暗号方式(速いが鍵の受け渡しが困難)
送信者と受信者が「同じ鍵」を使って暗号化・復号を行います。処理が圧倒的に速く大容量の通信に向いていますが、「その共通鍵をどうやって安全に相手に渡すのか?」という鍵配送問題があります。もし共通鍵が漏れたら丸見えです。
公開鍵暗号方式(遅いが鍵の受け渡しが容易)
「公開鍵」と「秘密鍵」という数学的に対になる2つの鍵をペアで作ります。片方で処理したものはもう片方でしか元に戻せないし、公開鍵から秘密鍵を逆算するのは(現在は)数学的に極めて困難です。
この一方通行の性質から、主に2つの使い方があります。
1つ目は暗号化。公開鍵で暗号化したデータは、対応する秘密鍵でしか復号できません。開いた錠前(公開鍵)を配っておき、みんなに箱にガチャンと鍵をかけて送ってもらうイメージ。開けられるのは錠前の鍵(秘密鍵)を持っている自分だけです。
2つ目はデジタル署名。こちらは実印と印鑑証明書の関係に近いです。実印(秘密鍵)は本人だけが持っていて、押印された書類を受け取った側は、役所で取得した印鑑証明書(公開鍵)と照合して「確かにこの人が押したものだ」と確認できます。印鑑証明書はいくらコピーしても実印の偽造はできない、という点も公開鍵暗号と同じです。後で出てくる証明書の仕組み(トラストチェーン)は、こちらの性質を活用しています。
公開鍵は世界中にバラ撒いてOKなので、鍵配送問題は解決します。ただし、公開鍵暗号の数学的演算(楕円曲線の点乗算やRSAのべき乗剰余)は共通鍵暗号(AES等)と比べて桁違いに重く、通信データを丸ごと公開鍵暗号で処理するのは現実的ではありません。
ハイブリッド暗号とTLSハンドシェイク
共通鍵と公開鍵、どちらにも弱点がある。SSL/TLSでは「両方のいいとこ取り」をしたハイブリッド暗号方式を使います。
現在主流のTLS 1.3では、ECDHE(楕円曲線ディフィー・ヘルマン鍵共有)という仕組みで共通鍵を安全に共有します。大まかな流れは次のとおりです。
- クライアントとサーバがそれぞれ使い捨ての秘密鍵を生成し、そこから導出した鍵共有の公開パラメータ(Key Share)だけを交換する(ECDHE鍵共有)
- 双方が相手の公開パラメータと自分の秘密鍵から同じ「共有鍵(共通鍵)」を導出する(鍵自体はネットワークを流れない)
- 以降は、この共通鍵による高速な共通鍵暗号(AEAD)で通信する
ブラウザでURLにアクセスすると、このやり取りが最初にミリ秒単位で行われています。TLS 1.3では証明書を含むハンドシェイクメッセージもハンドシェイク鍵で暗号化されるため、TLS 1.2以前と比べて盗聴耐性が高くなっています。
ECDHEでは通信セッションごとに使い捨ての鍵ペアを生成するため、仮に後からサーバの長期秘密鍵が漏洩しても、過去の通信を遡って解読することはできません。この性質はPFS(Perfect Forward Secrecy)と呼ばれ、TLS 1.3では初回接続(フルハンドシェイク)時にDHE/ECDHEによる鍵共有が必須(実運用上はほぼECDHE)となり、標準的に確保されています。
【コラム】Harvest Now, Decrypt Later (HNDL) 攻撃と耐量子暗号
PFSで秘密鍵単体の漏洩には強くなったけど、もし数十年後に現代の公開鍵暗号を瞬時に解読できる超高性能な「量子コンピュータ」が完成したらどうなるの?
と、暗号の世界ではかなり真剣に議論されており「Harvest Now, Decrypt Later(HNDL)」と呼ばれる攻撃シナリオが想定されています。今のうちに暗号化された通信をそのまま収集しておき、将来に量子コンピュータが実用化された時に一気に解読するというものです。
量子コンピュータでも解読が困難となるように、2024年にNIST(米国国立標準技術研究所)が「耐量子計算機暗号(PQC: Post-Quantum Cryptography)」を正式に標準化しました(FIPS 203/204/205)。現在はこれをTLSや各種プロトコルに組み込む実装が急ピッチで進んでいます。
残念ながら、暗号と解読のイタチごっこは、どこかでパラダイムシフトが起きない限り、量子の領域でも続く模様です。
トラストチェーンと認証局
さて、暗号化で盗聴は防げました。しかし問題がもう一つあります。
本当に、最初にもらった「公開鍵」は、アクセスしたい本物のサーバが出したモノでしょうか?
フリーWi-Fiに潜む攻撃者が自分の公開鍵を渡してきたら、皮肉にも攻撃者との間に安全な暗号通信が確立されてしまいます(中間者攻撃)。さっき触れた「フリーWi-Fiでの注意」は、まさにこのリスクです。
ここで登場するのが「デジタル証明書」と「認証局(CA)」を用いたPKI(公開鍵基盤)です。
- サーバ運営者は、信頼できる第三者機関(ルートCA、中間CA)に申請し、「この公開鍵は間違いなく
example.qiita.comのものです」というデジタル署名(実印)をもらいます。 - OSやブラウザには、あらかじめ世界的に信頼された「ルートCAの印鑑証明書(ルート証明書)」が最初からインストールされています。
ブラウザはサーバから証明書を受け取ると、自分が最初から持っている印鑑証明書リストと照らし合わせ、「あ、中間CAさんとルートCAさんが『本物やで』って実印押してはるから、この公開鍵は信じてOKやな!」と判断します。
さっき出てきた証明書の種類(DV/OV/EV)の違いは、認証局が何をどこまで検証して実印を押したかの差です。DVはドメインの所有権だけ、OVは組織の実在、EVは厳格な審査を経てから発行されます。
【コラム】証明書とFQDN(ワイルドカードとSAN)
SSL証明書は「このサーバは本物です」と証明するものではなく、厳密には「このFQDN(完全修飾ドメイン名)を名乗る権利を持っているのは私です」を証明するものです。
昔は1つの証明書に1つのFQDN(Common Name)しか書けませんでしたが、今は「SAN(Subject Alternative Name)」という拡張領域に blog.qiita.com など複数のFQDNを併記するのが一般的です。また、*.qiita.com のようにサブドメインをひとまとめにして証明する「ワイルドカード証明書」も便利ですが、漏洩したときの影響範囲が大きいため、用途に応じた使い分けがインフラ設計の腕の見せ所です。
証明書を正しく設定する
ここからは、サービスを提供する側(サーバ管理者・インフラエンジニア)が気を付けるべきポイントです。
中間証明書のチェーンを忘れない
サーバに「自分の証明書(エンドエンティティ証明書)」だけを設定し、「中間CA証明書」を一緒に設定し忘れるケースが後を絶ちません。
PCのブラウザだと、中間証明書をAIA(Authority Information Access)で自動補完してくれるため問題なくアクセスできてしまい、テスト時に気付けないのが厄介です。しかしモバイルアプリや一部のAPIクライアント、古いブラウザでは補完機能が無いため「PCでは見れるのにスマホだとエラーになる」という連絡から、やるせない調査が始まります。
対策はシンプルで、証明書ファイルにエンドエンティティ証明書と中間CA証明書を正しい順序で結合(チェーン)して設定します。
Mixed Content を排除する
HTTPSで配信しているページ内に、画像やJavaScriptなどをHTTP(非暗号化)で読み込んでいる状態が「Mixed Content(混在コンテンツ)」です。ブラウザは警告を出したり、HTTP部分のリソースをブロックします。HTTPS化は「ページ単位」ではなく「読み込むリソースすべて」で徹底する必要があります。
HSTSでHTTPSを強制する
Mixed ContentやSSLストリッピング攻撃(HTTP→HTTPSリダイレクトを攻撃者が阻止する手口)への対策として有効なのがHSTS(HTTP Strict Transport Security)です。サーバがレスポンスヘッダに Strict-Transport-Security を含めると、ブラウザは以降そのドメインへのアクセスをすべてHTTPSに強制します。ユーザが http:// でアクセスしても、ブラウザ側で自動的に https:// に書き換えてからリクエストを送るため、平文通信が発生しなくなります。
証明書を運用維持する
設定が終わったら、次は運用です。
Let's EncryptとACMEによる自動化
PKIの仕組み上、証明書の取得には認証局への申請が必要です。かつては有料で手続きも煩雑でしたが、2016年にサービスを開始したLet's Encryptがこの状況を変えました。
Let's Encryptは無料のDV証明書を発行する認証局で、ACME(Automatic Certificate Management Environment)プロトコルにより証明書の取得・更新を完全自動化しています。「お金がないから暗号化できない」という言い訳が通じなくなり、W3Techsの統計では全Webサイトの約30%がLet's Encrypt発行の証明書を使っています。
有効期限の短縮と自動更新
たまにニュースになったりする証明書の有効期限切れは、よくある障害原因です。
冒頭のNTPの話と繋がりますが、ブラウザ(やAPIクライアント)はサーバの時刻ではなく自分の時計で証明書の有効期限をチェックするため、期限が切れた瞬間にアクセス不能になります。
証明書の最大有効期間は年々短くなっています。
理由は主に2つで、1つは秘密鍵が漏洩した場合の被害期間を短くするため、もう1つは証明書の自動更新を前提とした運用を業界全体に定着させるためです。有効期間が短ければ、仮に鍵が漏れても悪用できる期間が限られますし、手動更新に頼っている運用は自然と淘汰されます。CA/Browser ForumのBallot SC-081(2025年可決)により、段階的に短縮されることが決まりました。
| 適用時期 | 最大有効期間 |
|---|---|
| 〜2026年3月 | 398日 |
| 2026年3月〜 | 200日 |
| 2027年3月〜 | 100日 |
| 2029年3月〜 | 47日 |
手動で更新していては到底間に合いません。Let's EncryptのACME(certbotなど)による自動更新が事実上必須です。
加えて、DatadogやZabbixなどの監視ツールで「証明書の残り日数」を監視し、自動更新が失敗した場合に備えてアラートを上げる設定をしておくのも良いでしょう。
秘密鍵の漏洩と証明書の失効
万が一、秘密鍵が漏洩した場合、有効期限内であっても即座に証明書を失効(Revoke)する必要があります。
失効情報をクライアントに伝える方式は大きく3つ。
- CRL(Certificate Revocation List)
認証局が「失効した証明書のリスト」を公開する方式で、リストが肥大化すると遅くなるのが難点です。 - OCSP(Online Certificate Status Protocol)
特定の証明書の状態をリアルタイムで認証局に問い合わせる方式で、CRLより効率的ですが認証局への依存度が高くなります。 - OCSPステープリング
サーバ側がOCSPレスポンスを事前に取得しておきTLSハンドシェイク時にクライアントに渡す方式で、プライバシーとパフォーマンスの両面で有利です。
サーバ側としてはOCSPステープリングを有効にしておくのが定石です。
設定を確認する
証明書の設定が正しいかどうかは、外部ツールで検証できます。
SSL Labs Server Test が定番で、証明書チェーン、TLSバージョン、暗号スイート、既知の脆弱性をまとめてチェックしA〜Fでグレード判定してくれます。
コマンドラインなら openssl s_client -connect example.com:443 で証明書チェーンやTLSバージョンを確認でき、CI/CDパイプラインへの組み込みも可能です。
本番公開前に一度はSSL Labsでスキャンし、A判定を確認しておくと安心です。
おわりに
利用者から見れば「HTTPSかどうか」「証明書は正当か」を確認するだけの話ですが、提供者としては証明書チェーンの設定、有効期限47日時代に向けた自動更新、失効への備えと、やることは減るどころか増えています。
前回のNTPと同じく、SSL/TLSも「動いてて当たり前」と思われている仕組みです。エラーが出てから初めて存在に気付かれるインフラの宿命だからこそ、「基本の"キ"」を押さえておくのが大切です。
お断り
記事内容は個人の見解であり、所属組織の立場や戦略・意見を代表するものではありません。
あくまでエンジニアとしての経験や考えを発信していますので、ご了承ください。