Tech Learning Daily

2026-07-31 (Fri) — 第 15 号
AI が毎朝届ける、ソフトウェア技術の基礎解説
Network 🌿 基礎 ⏱ 約 7 分

HTTPS の鍵マークは、いったい何を保証しているのか?

本番の URL はどれも当然のように https:// で始まり、ブラウザには鍵マークが点いている。だがその鍵マークが点くまでの数十ミリ秒でブラウザとサーバーが何を確認し合っているのか、通信内容が盗み見られないことだけを指しているのか、説明できるだろうか。

🎯 3 行まとめ
  • TLS ハンドシェイクが最初にやるのは暗号化そのものではなく「相手が本物かの確認」と「今回限りの鍵の合意」の 2 つで、鍵マークはこの両方が成立した結果である
  • サーバーの本人確認は、証明書の署名を OS/ブラウザ内蔵のルートストアまで辿れるかで判定しており、途中の署名を 1 つでも検証できなければ接続は拒否される
  • TLS 1.3 は鍵交換を毎回使い捨ての鍵(ECDHE)に統一したことで、仮にサーバーの秘密鍵が将来漏れても過去の通信は解読できない「前方秘匿性」を標準で持つ

TLS が解決しようとしている 3 つの問題

平文の HTTP には 3 つの弱点がある。通信経路の途中で内容を覗き見される盗聴、内容を書き換えられる改ざん、そして偽サーバーが本物のふりをするなりすましだ。TLS(Transport Layer Security)はこの 3 つに対応する形で、暗号化による機密性、改ざん検知による完全性、証明書による真正性の 3 つを提供するプロトコルとして設計されている。

ハンドシェイクとは、この 3 つを実際の通信が始まる前に確立するための最初のやり取りのことだ。鍵マークが点くのは、暗号化が始まったからではなく、この確立処理そのものが最後まで成功したことを示している。

共通鍵を、内容を送らずに「合意」する仕組み

公開鍵暗号(RSA や楕円曲線暗号など、公開鍵と秘密鍵のペアを使う方式)は安全だが計算コストが高く、ページ本体のような大量データの暗号化には向かない。そこで TLS はハンドシェイクの間だけ公開鍵暗号を使い、その後の通信本体は計算の軽い共通鍵暗号(同じ鍵で暗号化と復号を行う方式)に切り替える。この共通鍵をどう安全に決めるかが、ハンドシェイクの核心だ。

TLS 1.3 が使うのは ECDHE(楕円曲線ディフィー・ヘルマン鍵交換の、接続ごとに使い捨ての鍵ペアを生成する方式)だ。クライアントとサーバーはそれぞれ自分だけの秘密の数値を持ち、そこから計算した公開値だけを交換する。回線上には公開値しか流れないのに、双方が自分の秘密の数値と相手の公開値を掛け合わせると同じ値にたどり着く。これが共通鍵の材料になる。

🍱 たとえるなら

2 人が離れた場所で同じ色の塗料を作りたいが、途中の郵便は誰にでも読まれると考えてほしい。まず 2 人で公開の共通色(黄色としよう)を決めて共有する。それぞれが自分だけの秘密の色を黄色に混ぜ、できた混合色だけを相手に送る。受け取った混合色にさらに自分の秘密の色を混ぜると、2 人とも最終的に同じ色にたどり着く。混合色から元の秘密の色を逆算するのは現実的な時間ではできない。ECDHE がやっているのは、この「途中経過だけを見せて、同じ結論に別々にたどり着く」計算を数値で行っていることに他ならない。

証明書チェーンは、何の「本物」を保証しているのか

鍵の合意ができても、合意した相手が正しいドメインの持ち主だという保証にはならない。ここで使われるのが証明書チェーンだ。サーバーが提示する証明書(そのドメインの公開鍵を含む)は上位の認証局が署名しており、その認証局の証明書もさらに上位の認証局が署名している。この連鎖を、ブラウザや OS があらかじめ信頼済みとして持っているルートストア(トラストストアとも呼ぶ、少数の信頼済みルート証明書の一覧)まで署名を検証しながら遡れれば、証明書は正当と判定される。途中の署名が 1 つでも合わなければ、その場で接続は拒否される。

鍵マークが付けば運営者そのものが信頼できると思うかもしれない。しかし実際に証明書が保証しているのは「このドメインの所有者と通信できている」ことだけで、Let's Encrypt のような無料の認証局が発行する証明書の大半はドメインの制御権を確認しているにすぎず、運営組織が実在の企業か詐欺目的かまでは一切保証しない。

1 往復のやり取りで、実際に何が送られているか

TLS 1.3 のハンドシェイクは 1 回の往復(1-RTT)で完了する。旧バージョンの TLS 1.2 が 2 往復かかっていたのに対し、クライアントが最初のメッセージに ECDHE の公開値をあらかじめ含めることで、サーバー側の応答を待たずに鍵の材料を渡せるようになったからだ。

Client                        Server
  │──ClientHello(鍵候補)──────▶│
  │                     鍵を計算・証明書準備
  │◀─ServerHello(鍵)───────────│
  │◀─証明書+署名(以降は暗号化)──│
  │──Finished──────────────────▶│
  │◀════ ここからアプリデータ ═▶│

ClientHello には ECDHE の公開値の候補と対応可能な暗号方式の一覧が入る。サーバーは ServerHello で使う方式と自分の公開値を返した時点でこの鍵の材料が揃うため、続く証明書やFinished メッセージ(ここまでのやり取りが改ざんされていないことを示す確認メッセージ)はもう暗号化された状態で送られる。双方が Finished を確認できて初めて、鍵マークが点きアプリケーションデータが流れ始める。

鍵が使い捨てだと、なぜ将来の漏洩に強くなるのか

TLS 1.3 では、サーバーの秘密鍵を使って共通鍵そのものを暗号化して送る古い方式(静的 RSA 鍵交換)が廃止された。この方式では、通信を記録しておいた攻撃者が後年サーバーの秘密鍵を入手すれば、過去に記録した全セッションを一括で復号できてしまう。ECDHE の鍵ペアは接続のたびに新しく生成され、ハンドシェイクが終わると破棄される。そのため後からサーバーの長期秘密鍵が漏れても、過去の各セッションを個別に復号する材料はもう存在しない。この性質を前方秘匿性と呼び、TLS 1.3 では全ての鍵交換方式で必須になっている。

💼 実務でどう出会うか

ロードバランサーで TLS をどこで終端するか設計するとき、証明書の期限切れで対象ドメイン全体が一斉に接続不可になる障害、あるいは社内プロキシが挟む中間者用の証明書をクライアントのトラストストアに入れ忘れて curl が certificate verify failed で落ちるトラブルは、いずれもこの証明書チェーンの検証で起きている。

⌨️ 手を動かす(5 分)

openssl s_client で実際のハンドシェイクを行い、ネゴシエートされたプロトコルバージョンと、証明書チェーンの検証結果を確認する。

echo | openssl s_client -connect example.com:443 2>/dev/null | grep -E "New, TLS|Verify return code"

New, TLSv1.3, Cipher is ... の行にネゴシエートされたプロトコルバージョンと選ばれた暗号方式が表示され、Verify return code: 0 (ok) が出ていれば証明書チェーンがルートストアまで検証できたことを意味する。ドメインを変えて実行すると、サイトによって選ばれる暗号方式が異なるのも観察できる。

🙅 よくある誤解
  • 鍵マークが付いていれば、そのサイトの運営者は信頼できる — 証明書が保証するのはドメインの所有者と通信できていることだけで、運営組織が実在の企業か詐欺目的かは一切保証しない。
  • HTTPS は暗号化さえされていれば安全で、証明書の検証は形式的な手続きにすぎない — 証明書チェーンの検証こそが、暗号化した相手が本物のサーバーか中間者攻撃者かを見分ける唯一の手段であり、暗号強度だけでは相手の正体を保証できない。
  • 共通鍵さえ手に入れば、後で秘密鍵が漏れても過去の通信を解読できる — TLS 1.3 の ECDHE は接続ごとに鍵を使い捨てるため、後からサーバーの長期秘密鍵が漏れても、過去の個別セッションを復号する材料はもう残っていない。
📖 用語ミニ辞典
証明書チェーン
サーバー証明書から上位の認証局証明書へと連なる署名の連鎖。ルートストアまで辿れれば正当と判定される。
ルートストア
OS やブラウザがあらかじめ信頼済みとして内蔵する、少数のルート証明書の一覧。トラストストアとも呼ぶ。
ECDHE
楕円曲線ディフィー・ヘルマン鍵交換。接続ごとに使い捨ての鍵ペアを生成し、公開値の交換だけで共通鍵を導出する方式。
前方秘匿性
長期の秘密鍵が将来漏れても、過去に記録されたセッションを復号できない性質。使い捨ての鍵交換によって成立する。
Finished メッセージ
ハンドシェイクのやり取りが改ざんされていないことを双方が確認するための、暗号化された確認メッセージ。
🔗 もっと深く
最近の記事

コネクションプールが枯渇すると、なぜアプリ全体が固まるのか?

DB 接続の確立コストを省くのがコネクションプールだが、枯渇時はアプリ側プールが待ち行列とタイムアウト例外を起こすのに対し、DB サーバー自体の max_connections 超過は待たせず即座に接続拒否になる。検知にはプールのメトリクス監視が必要。
DB🌿 基礎⏱ 約 7 分2026-07-29

DB のインデックスはなぜ速いのか? B+Tree の中を覗く

B+Tree は 1 ノードに数百キーを詰めて木を横に広く浅く保つことで検索を O(log N) に抑える一方、インデックスが増えるほど書き込みのたびに複数の木を更新し、ページ分割が連鎖するコストを払うことになる。
DB🌿 基礎⏱ 約 7 分2026-07-28

ALB と NLB、同じ「ロードバランサー」なのに何が違うのか?

ALB は L7 で HTTP の中身を読んでルーティングし、NLB は L4 で TCP/UDP の接続だけを見て振り分ける。idle timeout・deregistration delay・cross-zone load balancing のデフォルト値の違いと使い分けの判断基準を解説。
Network🌿 基礎⏱ 約 8 分2026-07-27

AI エージェントに自律実行を任せるとき、権限・証跡・コストはどう設計するのか?

自律実行する LLM エージェントは OAuth スコープで権限を最小化し、破壊的操作の手前にガードレールと監査ログを置く必要がある。プロンプトキャッシュの料金倍率でコストを抑える設計も解説。
AI🌳 応用⏱ 約 8 分2026-07-26