chikaku

且听风吟

永远是深夜有多好。
github
email

TLS1.3 通信プロセス

TLS1.3 通信の手順の整理は、基本的には https://tls13.xargs.org から翻訳されました。元の文書を参照することをお勧めします。

クライアント:鍵ペアの生成#

(client_priv, client_pub) として記述します。

クライアント:クライアントハローパケットの平文送信#

主な内容は次のとおりです。

  • ランダムなクライアントランダム
  • クライアントがサポートする暗号スイート
  • クライアントがサポートするプロトコルバージョン
  • 要求されたサーバー名 SNI(Server Name Indication)
  • PSK(pre-shared-keys)プリ共有鍵モード
  • Key Share 公開鍵リスト(client_pub)
  • セッションチケット
  • 圧縮方法など...

SNI フィールドにより、サーバーは同じ ipグループで複数の TLS サービスを提供できます。ハンドシェイクプロセス中に、SNI に基づいて対応する証明書を返します。

Key Share 拡張は、クライアントがサーバーが受け入れる可能性が高い公開鍵と暗号アルゴリズムの 1 つ以上を送信します。サーバーが受け入れる場合、Server Hello の後続のデータは暗号化されて転送されます。事前にキーエクスチェンジが行われるのと同じです。サーバーが受け入れられない場合は、再試行のために Retry Hello Request メッセージが返されます。

セッションチケットは、接続が確立された後にサーバーから送信され、クライアントは再接続のためにこのデータを保存できます。

PSK の使用方法については、When do clients use TLS in PSK mode?を参照してください。

サーバー:鍵ペアの生成#

(server_priv, server_pub) として記述します。

サーバー:サーバーハローパケットの平文送信#

主な内容は次のとおりです。

  • ランダムなサーバーランダム
  • 暗号スイートの選択
  • 公開鍵の選択
  • プロトコルバージョンの選択
  • Key Share(server_pub)の返却
  • 圧縮方法など...

サーバー:ハンドシェイクキーの計算#

以下の情報を使用してハンドシェイクキーを計算します。

  • Client Hello Packet から取得した client_pub
  • サーバーが生成した server_priv
  • SHA384 (ClientHello + ServerHello) で送信されたメッセージのハッシュ値を計算します。

以降のハンドシェイクプロセスは、このキーを使用して暗号化されます。

クライアント:ハンドシェイクキーの計算#

以下の情報を使用してハンドシェイクキーを計算します。

  • Server Hello Packet から取得した server_pub
  • クライアントが生成した client_priv
  • SHA384 (ClientHello + ServerHello) で送信されたメッセージのハッシュ値を計算します。

以降のハンドシェイクプロセスは、このキーを使用して暗号化されます。

サーバー:証明書の暗号文送信#

サーバーは、Client Hello で指定された SNI に基づいて証明書を返し、検証を行います。

証明書の検証と発行#

  • サーバーは自分自身の鍵ペア(host_priv、host_pub)を生成し、host_pub とドメイン情報、地域情報などを組み合わせて host_info を CA(証明書機関)に送信します。
  • CA は申請者情報を審査し、自身の秘密鍵 CA_priv を使用して hash (host_info) を暗号化して署名 SIG を生成し、最終的に SIG と host_info を証明書としてサーバーに発行します。
  • クライアントはサーバーから証明書を取得した後、インストールされている CA の公開鍵を使用して署名 SIG を復号化し、元のデータ CA_pub (SIG) を取得します。
  • クライアントは証明書から host_info を取り出し、hash (host_info) を自分で計算し、検証と復号化されたデータが一致するかどうかを確認します。

証明書の発行

信頼チェーン#

一部の場合、証明書はサブ CA によって発行される場合があります。クライアントが証明書を要求すると、サーバーは中間証明書と自身の証明書を一緒に返します。

  • クライアントはまず、インストールされている CA の公開鍵を使用して中間証明書を検証し、中間証明書の公開鍵を取得します。
  • クライアントは次に、中間証明書の公開鍵を使用してサーバー証明書を署名検証します。

信頼チェーン

サーバー:証明書の検証のための暗号文送信#

前の手順により、クライアントは証明書(およびその中の公開鍵)が現在の要求されたサービス名に属していることを確認できますが、このサーバーがこの証明書の所有者であることを証明することはできません。したがって、サーバーは証明書が発行される前に作成した秘密鍵 host_priv を使用してハンドシェイクメッセージの要約を暗号化してクライアントに返します。クライアントは証明書の host_info から公開鍵 host_pub を取り出し、このデータを復号化してハンドシェイクメッセージの要約を自分で計算し、一致するかどうかを比較します。これにより、クライアントはこの接続のセキュリティを確認できます。

サーバー:ハンドシェイク終了検証メッセージの暗号文送信#

サーバーはハンドシェイク段階のすべてのメッセージをハッシュして検証メッセージとしてクライアントに送信します。

サーバー:アプリケーションキーの計算#

サーバーは、Handshake Key と Client Hello からサーバーハローまでのすべての情報をハッシュしてアプリケーションキーを計算します。これは、データ転送段階での対称キーです。

クライアント:アプリケーションキーの計算#

クライアントは同じ方法でアプリケーションキーを計算します。

クライアント:ハンドシェイク終了の暗号文送信#

クライアントはハンドシェイク段階のすべてのメッセージをハッシュして検証メッセージとしてサーバーに送信します。

これにより、クライアントとサーバー間で Application Key を使用して対称暗号化通信が行われます。

サーバー: Session Ticket 1 の暗号文送信#

サーバーはクライアントに対して Session Ticket を提供し、新しいセッションを迅速に開始するために計算とネットワーク遅延を大幅に削減します。以下を含みます。

  • Ticket Lifetime 有効期間
  • Ticket Age Add(各チケットごとに異なる)
  • Ticket Nonce ランダムな値(各チケットごとに異なる)
  • Session Ticket

Ticket Age Addは、サーバーが生成するランダムなミリ秒数です。クライアントは Session Ticket を使用して接続を復元する際に、ticket_age(Session Ticket を受け取ってから現在までの時間差を表す)にこの値を加えて混乱させる必要があります。サーバーはこの値を受け取り、クライアントの ticket_age と自身の計算した時間差が近いかどうかを検証し、一定の閾値を超える場合はこの接続を直接拒否できます。これにより、Session Ticket の再利用によるリプレイ攻撃をある程度防ぐことができます。

サーバー: Session Ticket 2 の暗号文送信#

クライアント(たとえばブラウザ)は通常、複数の接続を送信し、各 Session Ticket は 1 回のみ使用できるため、サーバーは通常、複数の Session Ticket を返します。

参考文献:
RFC8446
xargs.org - TLS
xargs.org - x25519
Wikipedia - Shared_secret
Wikipedia - Pre-shared_key
Wikipedia - SNI
A walkthrough of a TLS 1.3 handshake
一文详解 HTTPS 与 TLS 证书链校验
SSL/TLS 协议详解 (中)—— 证书颁发机构
网络安全科普:奇妙的 SSL/TLS 证书(基础篇)

読み込み中...
文章は、創作者によって署名され、ブロックチェーンに安全に保存されています。