HTTPS/TLSの基礎
このドキュメントの目的
HTTPS/TLS の基礎を理解し、なぜOAuth 2.0/OIDCでHTTPSが必須かを把握することが目標です。
HTTP vs HTTPS
HTTP(暗号化なし)
[クライアント] ─────平文で送 信────→ [サーバー]
↑
盗聴可能(危険)
問題点:
- ❌ 通信内容が平文(誰でも読める)
- ❌ パスワード、トークンが盗聴される
- ❌ 中間者攻撃(MITM: Man-in-the-Middle)
HTTPS(暗号化あり)
[クライアント] ──暗号化された通信──→ [サーバー]
↑
盗聴しても読めない
HTTPS = HTTP + TLS
TLS(Transport Layer Security):
- 通信を暗号化するプロトコル
- SSL(Secure Sockets Layer)の後継
HTTPS通信の全体像
┌──────────────────┐ ┌──────────────────┐
│ │ │ │
│ クライアント │ │ サーバー │
│ │ │ │
│ ────────────────────────────────────────────────────── │
│ TLSハンドシェイク(暗号化前) │
│ ────────────────────────────────────────────────────── │
│ │ │ │
│ 1. ClientHello │ │ │
│ (暗号スイート)│──────────────────→│ 2. 受信 │
│ │ │ │
│ 4. 受信 │ │ 3. ServerHello │
│ ↓ │←──────────────────│ (暗号選択、 │
│ 5. 証明書検証 │ サーバー証明書 │ 証明書送信) │
│ - ドメイン確認 │ │ │
│ - 有効期限確認 │ │ │
│ - CA署名確認 │ │ │
│ ↓ │ │ │
│ 6. 鍵交換 │──────────────────→│ 7. 鍵交換 │
│ (暗号化鍵生成)│ │ (暗号化鍵生成)│
│ │ │ │
│ ────────────────────────────────────────────────────── │
│ 暗号化通信開始(TLS確立後) │
│ ────────────────────────────────────────────────────── │
│ │ │ │
│ 8. HTTPリクエスト│ │ │
│ GET /users │ │ │
│ ↓ │ │ │
│ ┌────────────┐ │ │ │
│ │暗号化 │ │──9. 暗号化データ──→│ 10. 復号 │
│ └────────────┘ │ │ ↓ │
│ │ │ 11. 処理実行 │
│ │ │ ↓ │
│ 13. 復号 │ │ 12. 暗号化 │
│ ↓ │ │ ↓ │
│ ┌────────────┐ │ │ ┌────────────┐ │
│ │200 OK │ │←─暗号化データ───── │ │200 OK │ │
│ │{user data} │ │ │ │{user data} │ │
│ └────────────┘ │ │ └────────────┘ │
│ │ │ │
└──────────────────┘ └──────────────────┘
ポイント:
- TLSハンドシェイク(1-7): 暗号化前の準備
- 暗号化通信(8-13): HTTP通信を暗号化
TLSが提供する3つのセキュリティ
| セキュリティ | 目的 | 効果 |
|---|---|---|
| 1. 暗号化(Confidentiality) | 通信内容を秘匿 | 盗聴されても解読不可能 |
| 2. 改ざん検知(Integrity) | 通信内容の改ざんを検知 | 中間者攻撃を防止 |
| 3. サーバー認証(Authentication) | 接続先が本物のサーバーか確認 | フィッシングサイトへの接続を防止 |
サーバー認証の流れ
1. クライアント → api.example.com に接続
2. サーバー → 証明書を提示
3. クライアント → 証明書を検証
- ドメイン名一致?
- 有効期限内?
- 信頼できるCA(認証局)が署名?
4. 検証OK → 暗号化通信開始
サーバー証明書
証明書とは何か(具体的に)
証明書の実体:
- ファイル: .pem、.crt、.cer等のテキストファイル
- 中身: 公開鍵 + メタ情報 + CAの署名
ファイル例:
server.crt( サーバー証明書ファイル)
server.key(秘密鍵ファイル)← 絶対に外部に出さない
証明書ファイルの中身(PEM形式):
-----BEGIN CERTIFICATE-----
MIIDXTCCAkWgAwIBAgIJAKL0UG+mRKu3MA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNV
BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX
(Base64エンコードされたデータ)
...
-----END CERTIFICATE-----
デコードすると:
Subject: CN=api.example.com(ドメイン名)
Issuer: CN=Let's Encrypt Authority X3(認証局)
Valid From: 2025-01-01 00:00:00 UTC
Valid To: 2026-01-01 00:00:00 UTC
Public Key: (2048 bit RSA)
Modulus: 00:c2:af:...
Exponent: 65537
Signature Algorithm: sha256WithRSAEncryption
Signature: 3d:5f:...
秘密鍵と公開鍵のペア
秘密鍵(server.key):
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCyr...
(絶対に外部に出さない)
-----END PRIVATE KEY-----
関係:
秘密鍵(server.key)← サーバーのみ保持
├─ TLS通信の復号に使用
└─ 漏洩すると通信が盗聴される
公開鍵 ← 証明書(server.crt)に含まれる
├─ クライアントに配布される
└─ 暗号化に使用
証明書の検証
クライアントが行う検証:
1. ドメイン名の一致
証明書のSubject = 接続先ドメイン
2. 有効期限の確認
現在時刻が Valid From 〜 Valid To の範囲内
3. 認証局の署名検証
信頼できるCA(Let's Encrypt、DigiCert等)が署名したか
秘密鍵の所有証明
TLSハンドシェイクで行われること:
1. サーバーが証明書を送信(公開鍵を含む)
↓
2. クライアントが証明書を検証(上記3項目)
↓
3. クライアントが公開鍵で暗号化したデータを送信
↓
4. サーバーが秘密鍵で復号
→ 秘密鍵を所有していることを証明
つまり、TLSは2つを確認:
- ✅ 証明書(公開鍵)が本物か(CAの署名で保証)
- ✅ 秘密鍵を所有しているか(復号できることで証明)
OAuth 2.0/OIDCでのHTTPS
OAuth 2.0/OIDCはHTTPS必須:
- Authorization Endpoint
- Token Endpoint
- Redirect URI(localhostを除く)
理由: トークンが平文で送信されるため
MTLS(相互TLS認証)
サーバーとクライアント両方の身元を確認する高度なセキュリティ:
詳細: MTLS(相互TLS認証)
TLSバージョン
TLS 1.2(推奨)
- 現在広く使われている
- 十分なセキュリティ
TLS 1.3(最新)
- より高速
- より安全
- 不要な機能を削減
OAuth 2.0/OIDC推奨: TLS 1.2以上
非推奨: TLS 1.0、TLS 1.1、SSL 3.0(脆弱性あり)
HTTPS通信の流れ(TLSハンドシェイク)
1. [クライアント] → ClientHello
- サポートする暗号スイート
2. [サーバー] → ServerHello
- 選択した暗号スイート
- サーバー証明書
3. [クライアント]
- 証明書検証
- 鍵交換
4. 暗号化通信開始
所要時間: 約100-200ms(RTT: Round Trip Time)
まとめ
学んだこと
- ✅ HTTPS = HTTP + TLS(暗号化)
- ✅ TLSの3つのセキュリティ(暗号化、改ざん検知、サーバー認証)
- ✅ サーバー証明書の役割(身元証明、公開鍵配布)
- ✅ MTLS(相互認証)= クライアント証明書も検証
- ✅ OAuth 2.0/OIDCはHTTPS必須
- ✅ FAPIはMTLS必須
HTTPSの重要性
OAuth 2.0/OIDCでは:
- Authorization Code、Access Tokenがネットワーク上を流れる
- HTTPだと盗聴されてアカウント乗っ取りのリスク
- HTTPS必須
次に読むべきドキュメント
- OAuth 2.0の基礎 - なぜOAuth 2.0が必要か
- OAuth 2.0のセキュリティ - セキュリティ脅威と対策
最終更新: 2025-12-18 対象: IDサービス開発初心者