はじめに
「このサイト、鍵マークがついてるから安全だよね?」
普段何気なく確認しているブラウザの鍵アイコン。でも、その裏側でどんな仕組みが動いているか、説明できますか?
この記事では、HTTPS通信を支える TLS(Transport Layer Security) の仕組みを図解で解説します。共通鍵暗号・公開鍵暗号・TLSハンドシェイク・証明書チェーンまで、一歩ずつたどります。
この記事は 「図解でわかるWeb技術の仕組み」シリーズ の第5回です。
第4回:DNS解決の流れを先に読むと、よりスムーズに理解できます。
1. HTTP vs HTTPS ― 何が違うのか
HTTPの問題点
HTTPは通信内容を 平文(暗号化なし) で送受信します。つまり、ネットワーク上の第三者がパケットを傍受すれば、パスワードもクレジットカード情報も 丸見え です。
HTTPSとは
HTTPS は、HTTPに TLS(Transport Layer Security) という暗号化レイヤーを追加したものです。
HTTPSが守る3つのこと
| 保護 | 内容 |
|---|---|
| 機密性(Confidentiality) | 通信内容を暗号化し、盗聴を防ぐ |
| 完全性(Integrity) | 通信途中のデータ改ざんを検知する |
| 認証(Authentication) | 通信相手が本物のサーバーであることを確認する |
HTTPSは「通信経路」を守るもの
HTTPSはサーバー自体のセキュリティを保証しません。フィッシングサイトもHTTPSを使えます。「鍵マーク = 安全なサイト」ではなく、「鍵マーク = 通信が暗号化されている」が正確な理解です。
2. 暗号化の基礎 ― 2つの暗号方式
TLSを理解するには、まず 2種類の暗号方式 を押さえる必要があります。
共通鍵暗号(対称鍵暗号)
暗号化と復号に 同じ鍵 を使う方式です。
平文 → [共通鍵で暗号化] → 暗号文 → [同じ共通鍵で復号] → 平文
| 項目 | 内容 |
|---|---|
| メリット | 処理が高速。大量データの暗号化に向いている |
| デメリット | 鍵をどうやって安全に相手に渡すか(鍵配送問題) |
| 代表例 | AES-256-GCM, ChaCha20-Poly1305 |
公開鍵暗号(非対称鍵暗号)
公開鍵 と 秘密鍵 のペアを使う方式です。公開鍵で暗号化したデータは、対応する秘密鍵でしか復号できません。
平文 → [公開鍵で暗号化] → 暗号文 → [秘密鍵で復号] → 平文
| 項目 | 内容 |
|---|---|
| メリット | 公開鍵は誰にでも渡せる。鍵配送の問題がない |
| デメリット | 処理が遅い(共通鍵暗号の100〜1000倍) |
| 代表例 | RSA, ECDSA(楕円曲線デジタル署名アルゴリズム) |
鍵交換アルゴリズム(ECDHE)は公開鍵暗号とは別物
ECDHE(楕円曲線ディフィー・ヘルマン鍵共有)は、公開鍵暗号の数学的原理を応用した 鍵交換アルゴリズム です。データの暗号化ではなく、共通鍵の「素材」を安全に共有するために使われます。TLS 1.3ではECDHEによる鍵共有が必須となっています。
TLSは「ハイブリッド方式」
TLSは2つの方式を組み合わせます。
1. 公開鍵暗号の技術(鍵交換アルゴリズム)で「共通鍵」を安全に生成する
2. 以降の通信は「共通鍵」で高速に暗号化する
これにより、安全性と速度を両立 しています。
3. TLSハンドシェイク ― 安全な通信路を確立する
HTTPSで通信する前に、クライアントとサーバーは TLSハンドシェイク を行い、暗号化の設定を合意します。
TLS 1.3のハンドシェイク手順
| ステップ | 送信元 | 内容 |
|---|---|---|
| 1. ClientHello | クライアント → | 対応TLSバージョン・暗号スイート一覧・乱数を送信 |
| 2. ServerHello | ← サーバー | 暗号スイートを選択・サーバー証明書・公開鍵を送信 |
| 3. 証明書検証 | クライアント | 認証局(CA)の署名を検証し、サーバーの正当性を確認 |
| 4. 鍵交換 | 双方 | ECDHE等で共通鍵の「素材」を交換し、共通鍵を生成 |
| 5-6. Finished | 双方 | 共通鍵で暗号化した検証メッセージを交換して完了 |
TLS 1.2 vs TLS 1.3
TLS 1.2: 2-RTT(2往復)でハンドシェイク完了
TLS 1.3: 1-RTT(1往復)でハンドシェイク完了 ← 高速化!
暗号スイートとは
暗号スイートは「どの暗号アルゴリズムの組み合わせを使うか」を定義したものです。
例: TLS_AES_256_GCM_SHA384
- TLS — プロトコル
- AES_256_GCM — 共通鍵暗号(AES 256bit、GCMモード)
- SHA384 — ハッシュアルゴリズム
4. 証明書チェーン ― 信頼の連鎖
TLSハンドシェイクのステップ3で、クライアントはサーバー証明書を検証します。この検証は 「証明書チェーン」 という信頼の連鎖に基づいています。
3つの登場人物
| 証明書 | 役割 |
|---|---|
| ルート認証局(Root CA) | 信頼の起点。OS/ブラウザにあらかじめ組み込まれている |
| 中間認証局(Intermediate CA) | ルートCAから信頼を委譲される。サーバー証明書を発行する |
| サーバー証明書(End-Entity) | 実際のWebサイトの証明書。ドメイン名と公開鍵を含む |
検証の流れ
サーバー証明書の署名を中間CAの公開鍵で検証
→ 中間CAの証明書の署名をルートCAの公開鍵で検証
→ ルートCAはOS/ブラウザに組み込み済み → 信頼できる!
チェーンが途切れると「この接続ではプライバシーが保護されません」という警告が表示されます。
Let's Encrypt ― 無料のSSL/TLS証明書
# certbot で Let's Encrypt 証明書を取得
sudo certbot --nginx -d example.com -d www.example.com
# 証明書の確認
sudo certbot certificates
# 自動更新の確認(90日ごとに更新が必要)
sudo certbot renew --dry-run
DV / OV / EV証明書の違い
| 種類 | 検証レベル | 費用 | 用途 |
|---|---|---|---|
| DV(Domain Validation) | ドメイン所有権のみ | 無料〜 | 個人・ブログ |
| OV(Organization Validation) | 組織の実在確認 | 有料 | 企業サイト |
| EV(Extended Validation) | 厳格な組織確認 | 高額 | 金融・ECサイト |
5. TLS 1.3 の改善点
TLS 1.3(2018年策定、RFC 8446)は、TLS 1.2から大幅に改善されています。
| 項目 | TLS 1.2 | TLS 1.3 |
|---|---|---|
| ハンドシェイク | 2-RTT | 1-RTT(0-RTT再接続も可能) |
| 暗号スイート | 多数(脆弱なものも含む) | 5つに厳選(安全なもののみ) |
| 前方秘匿性 | オプション | 必須(ECDHE) |
| RSA鍵交換 | 使用可能 | 廃止 |
| RC4 / 3DES | 使用可能 | 廃止 |
前方秘匿性(Forward Secrecy)とは
前方秘匿性あり(TLS 1.3):
秘密鍵が漏洩しても、過去の通信は復号できない
→ セッションごとに一時的な鍵ペアを生成するため
前方秘匿性なし(RSA鍵交換):
秘密鍵が漏洩すると、記録していた過去の通信をすべて復号可能
→ 固定の秘密鍵で共通鍵を暗号化するため
6. 実務で気をつけるポイント
Webサーバーの設定例(Nginx)
server {
listen 443 ssl http2;
server_name example.com;
# 証明書の設定
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
# TLS 1.2 以上のみ許可(1.0, 1.1は無効化)
ssl_protocols TLSv1.2 TLSv1.3;
# 安全な暗号スイートのみ使用
ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256';
ssl_prefer_server_ciphers on;
# HSTS(ブラウザにHTTPSを強制)
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
}
チェックリスト
| 項目 | やるべきこと |
|---|---|
| TLSバージョン | TLS 1.2以上のみ有効にする(1.0, 1.1は無効化) |
| 証明書の更新 | Let's Encryptは90日。自動更新を設定する |
| HSTS |
Strict-Transport-Security ヘッダーを設定する |
| HTTPリダイレクト | HTTP (80) → HTTPS (443) に301リダイレクトする |
| Mixed Content | HTTPS内でHTTPリソースを読み込まない |
7. まとめ
| 項目 | ポイント |
|---|---|
| HTTPS | HTTP + TLS で通信を暗号化。盗聴・改ざん・なりすましを防ぐ |
| 共通鍵暗号 | 同じ鍵で暗号化・復号。高速だが鍵配送が課題 |
| 公開鍵暗号 | 公開鍵/秘密鍵のペア。安全だが低速 |
| TLSハンドシェイク | 暗号スイート合意 → 証明書検証 → 鍵交換で安全な通信路を確立 |
| 証明書チェーン | ルートCA → 中間CA → サーバー証明書の信頼の連鎖 |
| TLS 1.3 | 1-RTTハンドシェイク、前方秘匿性必須、脆弱なアルゴリズムを廃止 |
次回予告
第6回では 「CDN の仕組みと役割」 を図解で解説します。エッジサーバー・キャッシュ・配信最適化の裏側を一歩ずつたどります。
シリーズ目次
| # | テーマ |
|---|---|
| 1 | HTTPリクエスト/レスポンスの仕組み |
| 2 | Cookie・Session・JWTの違い |
| 3 | OAuth 2.0 の仕組み |
| 4 | DNS解決の流れ |
| 5 | HTTPS・TLS通信の仕組み(この記事) |
| 6 | CDN の仕組みと役割 |
| 7 | WebSocket ― 双方向リアルタイム通信 |
| 8 | キャッシュ戦略(ブラウザ・サーバー・CDN) |
| 9 | CORS ― クロスオリジンの壁を理解する |
| 10 | REST API 設計の基本原則 |
「この記事が役に立った」と思ったら、LGTM とストックをお願いします。
@kotaro_ai_lab
AI活用や開発効率化について発信しています。フォローお気軽にどうぞ!




