メインコンテンツまでスキップ

RFC 2818 - TLS 上の HTTP (HTTPS) - 2. TLS 上の HTTP (HTTP Over TLS)

2. TLS 上の HTTP (HTTP Over TLS)​

中核原則 (Core Principle)​

概念的には非常にシンプル: HTTP/TLS は非常にシンプルです。TCP で HTTP を使用するのとまったく同じように、TLS 上で HTTP を使用します。

2.1. 接続の開始 (Connection Initiation)​

プロセス:

1. クライアント → サーバー: TCP 接続を確立 (ポート 443)
2. クライアント → サーバー: TLS ClientHello を送信
3. ↔ TLS ハンドシェイクプロセス ↔
4. ハンドシェイク完了後: クライアントは最初の HTTP リクエストを開始できる

要件:

  • ✅ HTTP クライアントは TLS クライアントとして動作する
  • ✅ 適切なポートに接続する (デフォルト 443)
  • ✅ ハンドシェイクを開始するために TLS ClientHello を送信する
  • ✅ すべての HTTP データは TLS の "application data" として送信されなければならない (MUST)

フロー例:

クライアント:
1. www.example.com:443 に TCP 接続
2. ClientHello を送信

サーバー:
3. ServerHello + Certificate を応答
4. ServerHelloDone

クライアント:
5. ClientKeyExchange
6. ChangeCipherSpec
7. Finished

サーバー:
8. ChangeCipherSpec
9. Finished

← TLS ハンドシェイク完了 →

クライアント:
10. 暗号化された HTTP リクエストを送信:
GET / HTTP/1.1
Host: www.example.com

2.2. 接続の終了 (Connection Closure)​

TLS は、セキュアな接続終了のための機能を提供します。

終了アラート (Closure Alert)​

定義:

  • 有効な終了 (Valid Closure): 適切な終了アラートを受信した
  • 不完全な終了 (Incomplete Close): 終了アラート送信後すぐに接続を閉じる
  • 早期終了 (Premature Close): 終了アラートを受信せずに接続を閉じた

要件:

  • ✅ 実装は接続を閉じる前に終了アラート交換を開始しなければならない (MUST)
  • ⚠️ 実装は終了アラート送信後に接続を閉じてもよい (MAY) (待機せずに)
  • ❌ 早期終了した接続はセッションを再利用してはならない (MUST NOT)

2.2.1. クライアントの動作 (Client Behavior)​

問題: HTTP は接続終了を使用してサーバーデータの終了を通知します。

クライアントは MUST:

  • ✅ すべての早期終了をエラーとして扱う
  • ✅ 受信したデータを切り捨てられた可能性があるものとして扱う
  • ✅ 接続を閉じる前に終了アラートを送信する

特殊なケース:

  1. Content-Length のないレスポンス:
HTTP/1.1 200 OK
Content-Type: text/html
[接続終了が終わりを示す]

← 早期終了がサーバーによるものか攻撃者によるものか区別できない →
  1. Content-Length が存在するが完全に読み取られていない場合:
HTTP/1.1 200 OK
Content-Length: 1000
[終了前に 500 バイトのみ受信]

← サーバーエラーか攻撃かを判断できない →

例外: 受信したデータが Content-Length と一致する場合は、完了として扱うべきです。

クライアント例:

✅ 通常の終了:
クライアント: closure_alert を送信
サーバーの closure_alert を待機
接続を閉じる

⚡ 高速終了:
クライアント: closure_alert を送信
すぐに接続を閉じる (待機しない)
← これによりサーバー側で不完全な終了が発生 →

2.2.2. サーバーの動作 (Server Behavior)​

RFC 2616 の要件: サーバーはクライアントの終了から適切に回復しなければならない (MUST)。

サーバーは SHOULD:

  • ✅ クライアントからの不完全な終了を受け入れる準備をする
  • ✅ このように終了された TLS セッションの再開を許可する
  • ✅ クライアントと終了アラートを交換しようとする
  • ⚡ 終了アラート送信後に接続を閉じてもよい (MAY)

実装注意事項:

持続的な接続を使用しない HTTP:
- サーバーは接続終了によってデータの終わりを通知
- しかし、クライアントはすでに終了アラートを送信し切断している可能性がある

2.3. ポート番号 (Port Number)​

デフォルトポート: 443

理論的根拠:

HTTP サーバーが期待: Request-Line (例: GET / HTTP/1.1)
TLS サーバーが期待: ClientHello

← 同じポートでは区別できない →

解決策: 異なるポートを使用
- HTTP: 80
- HTTPS: 443

例:

# HTTP (平文)
curl http://www.example.com:80/

# HTTPS (暗号化)
curl https://www.example.com:443/

2.4. URI 形式 (URI Format)​

プロトコル識別子: https:// (http:// の代わり)

例:

https://www.example.com/~smith/home.html
https://api.example.com:8443/v1/users
https://192.168.1.1/admin

URI コンポーネント:

https://www.example.com:443/path?query#fragment
↑ ↑ ↑ ↑ ↑ ↑
scheme host port path query fragment