読者です 読者をやめる 読者になる 読者になる

i remember nothing

文章の練習も兼ねています

プロフェッショナルSSLTLS 2.1章, 2.2章

TLS はいくつかのメッセージで構成される二者間のやりとりを安全にするために設計された暗号化プロトコルである。

2.1 Record プロトコル

TLS は Record Protorol によって実現されている。 このRecord Protocol がコネクション状の低レベルのメッセージの転送を全て担う。

ヘッダにContent type, バージョン、レコード長などの情報が格納されている。 そのヘッダの後にメッセージのデータがくっついている。

Record Protcol は通信の重要かつ高レベルな側面の抽象化の基盤となるプロトコルとなる。

  • メッセージの転送

レコードの長さには制限がある(26384byte)。それより長いバッファはRecordプロトコル によってチャンクに分割される。その逆もある。

  • 暗号化及び完全性の検証

TLS の最初の接続におけるメッセージは保護されない。 一旦ハンドシェイクが完了したらネゴシエーションしたパラメータに基づきレコード層による暗号化と完全性の検証が行われる。

  • 圧縮

TLSの圧縮機能は現在は使われていない。2012年にCRIME攻撃に利用された。

  • 拡張性

Record Protorolが担うのはデータ転送と暗号処理であり、他の部分はサブプロトコルで行う。 サブプロトコツの追加は簡単なのでTLSの拡張ができる。

TLSでは4つのサブプロトコルが規定されている。

2.2 Handshake プロトコル

2点間通信の両サイドはTLS接続で使うパラメータのネゴシエーションと認証をHandshakeプロトコルで行う。

以下の三つの一般的な流れがある。

  • サーバ認証を伴うフルハンドシェイク
  • 前回のセッションを再開する場合の一部のメッセージを省略したハンドシェイク
  • クライアントとサーバの認証を伴うハンドシェイク

Handshake protocol のメッセージのヘッダには メッセージの種類、 メッセージの長さという情報が含まれている。

2.2.1 フルハンドシェイク

TLS の接続はハンドシェイクから始まる。 クライアントがサーバとセッションを行ったことがない場合、TLSセッションを確立するためにフルハンドシェイクを実装することになる。

  • 一連の図

[Client]<–>[Server]

ClientHello ——-> | クライアントが新規のハンドシェイクを開始し、希望する暗号スイート、鍵交換の方法等のパラメータをサーバに送る

<——- ServerHello | サーバがパラメータを決定する

<——- Certificate | 証明書チェーンを送信する

<- ServerKeyExchange | マスターシークレット生成に必要な情報を送信する

<— ServerHelloDone | 終わったよ

ClientKeyExChange -> | マスターシークレット生成に必要な情報を送信

ChangeCipherSpec –> | 暗号通信に切り替えたよ

Finished ———-> | ハンドシェイクメッセージのMACを送る

<– ChangeCipherSpec | 暗号通信に切り替えたよ

<———- Finished | MACを送る

ClientHello

新規のハンドシェイクで常に送信される。

送信される。

主な情報は、

  • Version
  • Random

32byteのデータが含まれている。そのうち28byteは無作為に生成される。残りの4バイトはクライアント側の時刻情報が入る。

  • Session ID

既存のセッションがある場合に一意の識別子が入る。現在のセッションの状態をサーバが自身のキャッシュを持っておけるようになっている。

  • Cipher Suites

クライアントが対応可能な暗号スイートが格納されている。

  • Compression methods

クライアントが対応している圧縮方法を指定する。

  • Extentions

付加的なデータを運ぶ拡張が任意の数だけ含まれる。

などである。

ServerHello

構造はClientHelloと同じ

クライアントの要求プロトコルに答えられない場合プロトコルの別バージョンを返したりする

Certificate

X.509 証明書チェーンを運ぶ。(それ以外の形式のもの、たとえばPGP鍵を利用することもできる)

証明書チェーンはASN.1 の DER を使用してエンコードされた証明書を順番に並べる。

ServerKeyExchange

鍵交換に必要な付加的なデータを運ぶことができる。

ServerHelloDone

予定していたハンドシェイクを全て送信した時にサーバから送る合図。これを送ったらサーバはクライアントからメセージが来るのを待機する。

ClientKeyExchange

鍵交換に必要な情報をクライアントから送信するためのメッセージ。

ChangeCipherSpec

接続に使うパラメータに十分な方法を全て手に入れ、暗号処理に移行することを相手に通知する。 クライアントサーバの両方がこれを送信する。

Finished

ハンドシェイクが完了した合図。

このメッセージは暗号化されているので通信の両端で安全に交換できる。

verify_data というフィールドを持っていて そこに両端で受け取ったハンドシェイクメッセージをすべてハッシュ化した値とマスターシークレットを組み合わせて計算したものが入っている。

このメッセージは完全性が保証されているので第三者による捏造や改ざんはできない。

  • TLS 1.2 では Finished メッセージはデフォルトで 96 bit。SSL3.0では36 byteであった。

2.2.2 クライアント認証

クライアント認証を要求できるのは認証済みのサーバだけ。

CertificateRequest

サーバはクライアントに対する認証の要求を許容できる証明書の公開鍵と署名アルゴリズムの伝達に用いる。 許容できる認証局の一覧を送ることもある。

CertificateVerify

このメッセージにはその時点までにやりとりした全ハンドシェイクメッセージの署名が含まれる。

2.2.3 セッションリザンプション

フルハンドシェイクはクライアントがアプリケーションデータを送信できるようになるまでに2往復のやり取りを要する。

ハンドシェイク中はCPU負荷の高い処理がなんども必要になる。 省略版のハンドシェイクを使うことでオーバーヘッドの大半を回避できる。

セッションリザンプションは Sesson ID という識別子を用いてセッションの再開を可能にする仕組み。

サーバがセッションに対してSession IDを割り当てる。 クライアントとサーバはこのSession IDを一定期間保持しておく。 これで以前のセッションを再開しようとした場合、Session IDをデータに含めることで以前共有したマスターシークレットをつかって新しい暗号鍵を生成し、暗号通信に以降することができる。 これによりハンドシェイクが短くなりネットワーク上のやり取りが1往復で済む。

session ticket という似た別の方法もある。これはRFC 5077として導入されている。 こちらの方法ではクライアントが情報を全て保持する。