Upgrade to Pro — share decks privately, control downloads, hide ads and more …

『プロフェッショナルSSL/TLS』読書会 第2章 資料

『プロフェッショナルSSL/TLS』読書会 第2章 資料

Toru Sugino

May 12, 2017
Tweet

More Decks by Toru Sugino

Other Decks in Technology

Transcript

  1. 第2章 プロトコル プロフェッショナルSSL/TLS 読書会 2017/5/12(Fri) 杉野 透 (@hmikisato)

  2. 自己紹介 • 杉野 透 (@hmikisato) • 広告配信やマーケティング自動化のサーバサイドのエンジニアやっています • Python とか

    Go とか あと最近 Scala と戯れる生活 • Rust が気になるお年頃
  3. 2.1 Record プロトコル • TLSで通信する内容は、すべてこのバイナ リプロトコル上で構築される • typeの項により容易に拡張が可能 • fragmentの内容は、1つのバッファが複

    数の通信に分割されること・複数のバッ ファが1つの通信に結合されることがあり得 る • 圧縮は脆弱性となり得るので基本的に行 わない (TLS1.3で仕様から廃止) • 裏で送受信したバッファのシーケンスを数 えておく type: 1 octet • change_cipher_spec (20) • alert (21) • handshake (22) • application_data (23) major version: 1 octet minor version: 1 octet length: 2 octets (< 2 ^ 14) fragment: (length) octets
  4. 2.2 Handshake プロトコル • 使用する暗号スイートや、暗号化に必要 な情報の交換などを行う • ハンドシェイクのパターンはおおまかに以下 の3通り 1.

    サーバの認証を行うフルハンドシェイク 2. セッションを再開する簡略ハンドシェイク (セッションリサンプション) 3. クライアント認証を伴うハンドシェイク • msg_type: 1 octet • length: 3 octets • body: (length) octets
  5. 2.2.1 フルハンドシェイク クライアント サーバー ClientHello –––––––––––––––––––––––––––––––––––––––––> <––––––––––––––––––––––––––––––––––––––––– ServerHello <–––––––––––––––––––––––––––––––––––––––– Certificate

    *1 <––––––––––––––––––––––––––––––––– ServerKeyExchange *2 <––––––––––––––––––––––––––––––––––––– ServerHelloDone ClientKeyExchange –––––––––––––––––––––––––––––––––––> *3 ChangeCipherSpec –––––––––––––––––––––––––––––––––> Finished ––––––––––––––––––––––––––––––––––––––––––––> <––––––––––––––––––––––––––––––––– ChangeCipherSpec *3 <–––––––––––––––––––––––––––––––––––––––––––– Finished *1: サーバ認証が不要な場 合は省略 *2: マスターシークレットの生 成に不要な場合は省略 *3: Handshakeプロトコルでは ない通信であるため、最終的 なMACの計算に含まない 全体で2RTT
  6. ClientHello • Client 「Hello」 • 含まれる情報(抜粋) • Version: ClientがサポートするTLSのバージョンの上限 •

    Random: 乱数と時刻(任意)で決まる 32 octets の値 • Session ID: フルハンドシェイクでは空 • Cipher Suite: 暗号スイートが優先順に並ぶ • Compression methods: null固定です、イイネ? • Extensions: 拡張情報(SNI, ALPNなど)
  7. ServerHello, Certificate, ServerKeyExchange • ServerHello • 含まれる情報はClient Helloと同様 • ただし

    Client Hello からの提案から決定した値を返す • 必要なら Version の値を下げる • Session ID はここで決まる(乱数) • Certificate • デフォルトではX.509 証明書チェーンを返す。ただしルート証明書は省略されるべきとされる。 • ServerKeyExchange • 2.3, 2.4 節で詳しく
  8. ClientKeyExchange, ChangeCipherSpec • ClientKeyExchange • 2.3, 2.4 節で詳しく • ChangeCipherSpec

    • 「以後の通信は取り決めたとおりに暗号化する」という合図
  9. Finished • このメッセージは暗号化されている • verify_data を計算して相手に渡す • 合意した暗号スイートによって決められた PRF を使い、合意したマスターシークレットと、サーバおよ

    びクライアントで固定のラベルを用いて求められる、Handshake プロトコルで送受信したデータ全て (ただし ChangeCipherSpec は除く)のMAC値 • これが想定と異なるならHandshakeは失敗
  10. 2.2.2 クライアント認証つきフルハンドシェイク クライアント サーバー ClientHello –––––––––––––––––––––––––––––––––––––––––> <––––––––––––––––––––––––––––––––––––––––– ServerHello <–––––––––––––––––––––––––––––––––––––––– Certificate

    *1 <––––––––––––––––––––––––––––––––– ServerKeyExchange *2 <–––––––––––––––––––––––––––––––––––– CertificateRequest <––––––––––––––––––––––––––––––––––––– ServerHelloDone Certificate ––––––––––––––––––––––––––––––––––––––––––> ClientKeyExchange –––––––––––––––––––––––––––––––––––> ClientVerify –––––––––––––––––––––––––––––––––––––––––> *3 ChangeCipherSpec –––––––––––––––––––––––––––––––––> Finished ––––––––––––––––––––––––––––––––––––––––––––> <––––––––––––––––––––––––––––––––– ChangeCipherSpec *3 <–––––––––––––––––––––––––––––––––––––––––––– Finished 全体で2RTT
  11. CertificateRequest, CertificateVerify • CertificateRequest • 要求する証明書のタイプ • 要求する証明書の公開鍵および署名アルゴリズム • 許容する認証局の識別子(任意)

    • CertificateVerify • 本当に Certificate で送ってきた証明書の秘密鍵を持っているのかということをサーバに示す • ここまでに送受信した Handshake メッセージに、Clientの手元にあるはずの秘密鍵で署名をして 送る • サーバはクライアント証明書に付属の公開鍵で署名を検証する
  12. 2.2.3 セッションリサンプション クライアント サーバー ClientHello –––––––––––––––––––––––––––––––––––––––––> <––––––––––––––––––––––––––––––––––––––––– ServerHello <––––––––––––––––––––––––––––––––– ChangeCipherSpec

    *3 <–––––––––––––––––––––––––––––––––––––––––––– Finished *3 ChangeCipherSpec –––––––––––––––––––––––––––––––––> Finished ––––––––––––––––––––––––––––––––––––––––––––> 全体で1.5RTT フルハンドシェイクでは空にしていた Session ID に、 フルハンドシェイクのServerHelloで受け取ったSession IDを指定する Session Ticketについては 2.12 節
  13. 2.3 鍵交換 2.4 認証 暗号スイートによって鍵交換方式が決まる。認証もここで同時に行う RSA公開鍵暗号および(EC)DH鍵共有の細かいアルゴリズムは略 • RSA • クライアントが生成したプリマスターシークレットをサーバの公開鍵で暗号化し、

    ClientKeyExchange で送信 • サーバは秘密鍵で復号しプリマスターシークレットを共有する • DHE_RSA, ECDHE_RSA, ECDHE_ECDSA • サーバは、生成したパラメータを秘密鍵で暗号化し、ServerKeyExchangeで送信 • クライアントは、生成したパラメータをそのままClientKeyExchangeで送信 • クライアントは受け取ったパラメータをサーバの公開鍵で復号して認証とし、鍵共有によってプリマス ターシークレットを得る
  14. 2.5 暗号化 1. ストリーム暗号 2. ブロック暗号 3. AEAD 1. ブロック暗号ベース(GCM暗号利用モードのもの)

    2. ストリーム暗号ベース(ChaCha20-Poly1305) 用語については1章で説明済みなので略
  15. 2.5.1 ストリーム暗号 1. シーケンス番号(通信上には現れない)とRecordヘッダ、平文からMACを生成 2. 平文+MACをストリーム暗号で暗号化 (以下このスライドで + は連結) 3.

    Recordヘッダに暗号文をつけてRecordの完成
  16. 2.5.2 ブロック暗号 Mac-then-Encrypt (標準規格) 1. シーケンス番号とRecordヘッダ、平文からMACを生成 2. 平文⾧+MACの⾧さ+パディング⾧ がブロック⾧の整数倍になるようにパディングを作る 3.

    IVを作る 4. 平文+MAC+パディングを CBCモードで暗号化 5. RecordヘッダにIVと暗号文をつけてRecordの完成
  17. 2.5.2 ブロック暗号 Encrypt-then-Mac (拡張規格) 1. 平文⾧+パディング⾧ がブロック⾧の整数倍になるようにパディングを作る 2. IVを作る 3.

    平文+パディングを CBCモードで暗号化 4. シーケンス番号とRecordヘッダ、IV、暗号文からMACを生成 5. RecordヘッダにIVと暗号文をつけてRecordの完成
  18. 2.5.3 AEAD 1. 64ビットの nonce を作る 2. 平文をAEADのアルゴリズムで暗号化する。 同時にシーケンス番号とRecordヘッダを認証用データとしてAEADに渡す 3.

    Recordヘッダに nonce と暗号文をつけてRecordの完成
  19. 2.6 再ネゴシエーション • フルハンドシェイクを(既に合意した暗号化の下で)やり直す要求 • ClientHelloをサーバに送る • サーバがHelloRequestをクライアントに送り、それを受けてクライアントがClientHelloを返す • 必要なパターン

    1. クライアント証明書を要求しないエリアから要求するエリアへの移動 2. クライアント証明書を暗号化してのハンドシェイク(2段階ハンドシェイク) 3. 暗号化の強度の変更(CPUリソースの節約や暗号輸出規制対策。時代遅れ) 4. TLSのレコードカウンターがオーバーフローする(まずない) • 結構な脆弱性の温床になっていたりする(7.1節)この回避のために renegotiation_info 拡張がある(2.12節) • TLS 1.3 では廃止され、 post-handshake に置き換わる
  20. 2.7 Application Data プロトコル • 合意した暗号化方式で、上位プロトコル(HTTPSならHTTP)の内容を送受信する • Recordプロトコルに上位プロトコルの内容が乗るので、バッファの分割等が起こり得る

  21. 2.8 Alert プロトコル 2.9 接続を閉じる • Alertプロトコルは例外通知や、接続のcloseの通知に使われる • アラートのレベル(深刻度)は warning

    or fatal • fatal は即セッションを無効にして切断 • warning は それを受けた側が fatal で応じるかもしれないししないかもしれない • 接続の close の通知は、 close_notify の Alert を送り合うことで行う • 強制切断攻撃の対策のため • とはいえ実装の問題で強制切断攻撃の対策にはなってないのが現実(6.7節)
  22. 2.10.1 疑似乱数生成器 TLS PRF • TLS1.2のRFC (RFC 5246) で規定されたRFCで、HMACと何らかのHash関数(強度は最 低でもSHA256)で実装される

    P_hash(secret, seed) = concat(HMAC_hash(secret, A(i) + seed) for i = 1 to n) A(0) = seed A(i) = HMAC_hash(secret, A(i-1)) in i >= 1 PRF(secret, label, seed) = P_hash(secret, label + seed) 生成したい乱数の⾧さに応じてnの値は変わる
  23. 2.10.2 マスターシークレット 2.10.3 鍵生成 マスターシークレット PRF(pre_master_secret, “master secret”, client_random +

    server_random)[0..47] pre_master_secret は、鍵交換の方法により色々と異なる 鍵ブロック PRF(master_secret, “key expansion”, server_random + client_random) この乱数生成から、暗号鍵2つ、MAC鍵2つ(非AEADのみ)、IV2つ(ブロック暗号のみ) を取得する。
  24. 2.11 暗号スイート • TLSは、いくつもの暗号アルゴリズムや適用方法の組み合わせて通信のセキュリティを担保し ている。その組み合わせを指定するのが暗号スイート • 認証方式 • 鍵交換 •

    暗号化アルゴリズム、鍵⾧、暗号利用モード(ブロック暗号の場合) • MACのアルゴリズム(not AEADの場合) • PRF、Finished メッセージで使うHash、verify_dataのデータ⾧ (これらはTLS 1.2で追加) • 名前でだいたい分かるが、名前からだけでは分からないこともある • verify_dataのデータ⾧を明示的に規定しないあらゆる暗号スイートでは12 octetsになる • PRFとして TLS PRF が規定されているなら、Finished メッセージで使うHashはそれのベースにな るHashである
  25. 2.12 拡張 • Client Helloで一緒に送られる追加情報 • ALPN • application_dataプロトコルに乗せるプロトコルの合意を取る。 HTTP/2

    に使われるアレ • CT (証明書の透過性) • 楕円曲線の利用可能性 • 暗号スイートが楕円曲線暗号を利用する場合、対応している曲線群を送る • 現状はNISTの secp256r1 と secp384r1 のみ使われている状態 • Heartbeat • 例のアレ。UDP上のTLS(DTLS)などでTCPのkeepaliveと同様の目的で利用されるはずだったやつ • NPN • ALPNにとってかわられたやつ
  26. 2.12 拡張 • 安全な再ネゴシエーション • 以前のFinished メッセージ内のverify_dataをこれに乗せて送り合うことで安全な再ネゴシエーションを行 う • SNI

    • バーチャルホストでTLSを行う際に、どのホストの証明書を使うかをサーバに伝達する • これに対応していないクライアントはそろそろ切り捨て段階? • Session Ticket • サーバ側で保存していたSession IDとは対照的に、Session IDと紐づく合意情報を暗号化してそのまま Session Ticketとしてクライアント側に保存する。 クライアントはセッションリサンプション時にSession Ticketをサーバに送る。 サーバは復号してそのままその合意情報を使う • 鍵の管理が大変 & PFS が崩れてしまうので現状(in TLS 1.2)は使わない方がいい
  27. 2.12 拡張 • 署名アルゴリズムの提案 • クライアントが対応している署名とハッシュのアルゴリズムペアの提案 • なくても暗号スイートから推測できる in TLS

    1.2 • OCSPステープリング • サーバが直接証明書の失効情報を認証局に問い合わせ、その結果をクライアントに送信する • クライアントが認証局に問い合わせる必要がなくなるので通信コストが減る
  28. 2.13 プロトコルの限界 • TCPより下のレイヤは平文で通信される • IPレベルで暗号化したい場合は IPsec を使いましょう • ハンドシェイク開始から

    ChangeCipherSpec までは平文で通信される • Session ID とかクライアント証明書とか SNI 情報とかだだ漏れ • メッセージ⾧から通信内容を推測する研究もある • なお TLS 1.3 では • {Client, Server}Hello で(EC)DHの鍵交換を行った以降の全てのデータを暗号化する • Paddingで⾧さを誤魔化す
  29. 2.14 バージョン間の相違 SSL 3.0 → TLS 1.0 • PRF が

    HMAC base で規定 • マスターシークレットの作成にPRFを利用することが規定 • verify_data の生成にPRFを利用することが規定 • MAC として 標準化された HMAC を利用することが規定 • パディングのフォーマットを変更 • SSL 3.0 のパディング方式には POODLE による脆弱性が存在する • FORTEZZA が暗号スイートから外された
  30. 2.14 バージョン間の相違 TLS 1.0 -> TLS 1.1 • CBC 暗号利用モードで、明示的な

    IV を利用するようになった • 後年この変更によって対処された脆弱性がBEASTによって攻撃される • 問題のあるパディングに対してアラートを送信するよう実装要求を規定 • TLS拡張が参照される
  31. 2.14 バージョン間の相違 TLS 1.1 -> TLS 1.2 • AEAD および

    HMAC-SHA256 サポートが追加 • IDEA および DES 暗号スイートが削除 • いくつかのTLS拡張が仕様に取り込まれる • PRFの最低強度が SHA256 以上となる • PRF および verify_dataの⾧さが暗号スイートで規定できるようになった
  32. 2.14 バージョン間の相違 (EX) TLS 1.2 -> TLS 1.3 やばい