1. ハンドシェイクと鍵ネゴシエーションのプロセス
RSA ハンドシェイクとキー交換に基づくクライアント認証サーバーでは、例としてTLS/SSLハンドシェイク プロセスを詳細に説明します。
(1).client_hello
クライアントはリクエストを開始し、バージョン情報、暗号スイート候補リスト、圧縮アルゴリズム候補リスト、乱数、拡張フィールドなどの情報を含むリクエスト情報を平文で送信します。関連情報は次のとおりです。
サポートされている最も高い TSL プロトコル バージョンは、低位から高位まで、SSLv2 SSLv3 TLSv1 TLSv1.1 TLSv1.2 です。現在、TLSv1 より低いバージョンは基本的に使用されなくなりました。
クライアントがサポートする暗号スイートのリスト。各暗号スイートは、以前の TLS 原則の 4 つの機能の組み合わせに対応します: 認証アルゴリズム Au (身元検証)、鍵交換アルゴリズム KeyExchange (鍵合意)、対称暗号化アルゴリズム Enc (情報暗号化) ) および情報ダイジェスト Mac (完全性検証)。
サポートされている圧縮方式のリスト。後続の情報圧縮と送信に使用されます。
乱数random_C。後続の鍵生成に使用されます。
拡張フィールド拡張は、プロトコルおよびアルゴリズム関連のパラメータおよびその他の補助情報をサポートします。共通 SNI は拡張フィールドに属します。このフィールドの役割については後で別途説明します。
(2).server_hello+server_certificate+sever_hello_done
(a)server_hello、サーバーは、選択されたプロトコルのバージョン、選択された暗号スイート、選択された圧縮アルゴリズム圧縮方法、乱数random_Sなどを含むネゴシエーション情報結果を返します。乱数は後続のキーネゴシエーションに使用されます。
(b)server_certificates、認証とキー交換のためにサーバー側で対応する証明書チェーンを構成します。
(c)server_hello_done、server_hello 情報の送信が完了したことをクライアントに通知します。
(3).証明書の検証
クライアントは証明書の有効性を検証します。検証に合格した場合は、その後の通信が実行されます。そうでない場合は、さまざまなエラー条件に基づいてプロンプトと操作が行われます。正当性の検証には次のものが含まれます:
証明書チェーンの信頼された証明書パス。方法は上記のとおりです。
証明書が失効しているかどうかに関係なく、オフライン CRL とオンライン OCSP の 2 つの方法があり、クライアントが異なれば動作も異なります。
有効期限日、証明書が有効期間内であるかどうか。
ドメイン名ドメイン。証明書のドメイン名が現在のアクセス ドメイン名と一致するかどうかを確認し、一致ルールをその後分析します。
(4).client_key_exchange+change_cipher_spec+encrypted_handshake_message
(a) client_key_exchange、合法性検証に合格した後、クライアントは乱数 Pre-master を計算して生成し、証明書の公開キーで暗号化し、サーバーに送信します。
(b) この時点で、クライアントは、ネゴシエーションキーの計算に必要なすべての情報、つまり 2 つの平文乱数random_C とrandom_S、および独自の計算によって生成された Pre-master を取得しており、ネゴシエーションキーが計算されます。
enc_key=Fuc(ランダム_C、ランダム_S、プレマスター)
(c)change_cipher_spec。クライアントは、後続の通信が暗号化通信にネゴシエートされた通信キーと暗号化アルゴリズムを使用することをサーバーに通知します。
(d) encrypted_handshake_message。以前のすべての通信パラメータのハッシュ値とその他の関連情報を組み合わせてデータを生成し、ネゴシエートされたキー セッション シークレットとアルゴリズムを使用して暗号化し、データとハンドシェイク検証のためにサーバーに送信します。 ;
(5).change_cipher_spec+encrypted_handshake_message
(a) サーバーは、暗号化された Pre-master データを秘密鍵で復号し、以前に交換された 2 つの平文乱数 random_C および random_S に基づいてネゴシエーション キーを計算します。
(b) 以前に受信したすべてのメッセージのハッシュ値を計算し、クライアントから送信された encrypted_handshake_message を復号し、データとキーが正しいことを確認します。
(c) change_cipher_spec 検証に合格した後、サーバーはまた、change_cipher_spec を送信して、以降の通信では暗号化通信にネゴシエートされたキーとアルゴリズムが使用されることをクライアントに通知します。
(d) encrypted_handshake_message。サーバーは、現在のすべての通信パラメータ情報を組み合わせてデータを生成し、ネゴシエートされたキー セッション シークレットとアルゴリズムを使用してそれを暗号化し、クライアントに送信します。
(6). 握手の終了
クライアントは受信したすべての情報のハッシュ値を計算し、ネゴシエートされたキーを使用して encrypted_handshake_message を復号し、サーバーから送信されたデータとキーを検証し、検証に合格するとハンドシェイクが完了します。
(7).暗号化通信
ネゴシエートされたキーとアルゴリズムを使用して暗号化通信を開始します。
知らせ:
(a) サーバーはクライアントの検証、つまり双方向認証を要求することもできます. プロセス 2 で client_certificate_request 情報を送信できます. クライアントはまずプロセス 4 で client_certificate とcertificate_verify_message 情報を送信します. 証明書の検証方法は基本的に次のとおりですCertificate_verify_message はクライアントの秘密を使用します。鍵で暗号化されたデータはネゴシエートされた通信情報に基づいて取得され、サーバーは対応する公開鍵を使用してそれを復号化して検証できます。
(b) ECC など、使用される鍵交換アルゴリズムに応じて、ネゴシエーションの詳細は若干異なりますが、一般的には似ています。
(c) サーバー鍵交換の役割は、DH に基づく証明書、公開鍵がサーバー証明書に含まれていないなど、サーバー証明書に十分な情報が含まれていない場合に、サーバー証明書をクライアントに送信してプレマスターを計算することです。証明書は別途送信する必要があります。
(d) 変更暗号仕様は、現在使用されている暗号化通信方式を変更するようピアに通知するために実際に使用できますが、現時点では詳細な分析はありません。
(e) 変更メッセージは、ハンドシェイクまたは通信プロセス中の状態変化またはエラー メッセージを示すために使用されます。一般に、アラーム メッセージのトリガー条件は、接続が閉じられた、不正な情報が受信された、情報の復号化が失敗した、ユーザーがキャンセルしたことです。操作などが行われ、アラームメッセージが受信された場合、その後通信を切断するか、切断するかは受信者の判断となります。
2. セッションキャッシュハンドシェイク処理
ハンドシェイクの確立を高速化し、プロトコルによって引き起こされるパフォーマンスの低下とリソースの消費を軽減するために (詳細な分析については後述します)、TLS プロトコルにはセッション ID とセッション チケットという 2 種類のセッション キャッシュ メカニズムがあります。
セッション ID はプロトコルの標準フィールドであるサーバー側でサポートされるため、基本的にすべてのサーバーがサポートします サーバー側はセッション ID とネゴシエートされた通信情報を保存します Nginx の 1M メモリはマシン関連のセッション ID を約 4000 個保存できます多くのサーバー リソースを消費する情報。
セッションチケットはサーバーとクライアントの両方でサポートされる必要があります. 拡張分野に属し, サポート範囲は約 60% (信頼できる統計とソースなし). ネゴシエートされた通信情報は暗号化されてクライアントに送信されます.ストレージ。サーバーのみがキーを知っており、サーバー リソースを占有します。
2 つの主な違いは、ネゴシエーション情報を保存する場所と方法です。これは、http のセッションと Cookie に似ています。
両方が存在する場合、session_ticket (nginx 実装) が優先されます。
ハンドシェイクのプロセスは次のとおりです。
注: ハンドシェイク プロセスでは 1.5 往復がありますが、クライアントからサーバーに送信される最初のアプリケーション データはサーバーから返される情報を待つ必要がないため、ハンドシェイク遅延は 1*RTT です。
(1).セッションID セッションID
(a) クライアントとサーバーの間で接続が確立されている場合、サーバーはハンドシェイクが成功した後にセッション ID を返し、対応する通信パラメータをサーバーに保存します。
(b) クライアントがサーバーとの接続を再度確立する必要がある場合、client_hello のセッション ID に記録された情報が含まれ、それがサーバーに送信されます。
(c) サーバーは、受信したセッション ID に基づいてキャッシュ レコードを取得し、取得したキャッシュ レコードの有効期限が切れていない場合は、通常のハンドシェイク プロセスに従います。
(d) 対応するキャッシュレコードが取得されると、change_cipher_spec と encrypted_handshake_message 情報が返されますが、この 2 つの情報関数は類似しており、encrypted_handshake_message は現在の通信パラメータと master_secret のハッシュ値です。
(f) クライアントがサーバーによって暗号化されたデータを検証できる場合、クライアントは、change_cipher_spec および encrypted_handshake_message 情報も送信します。
(g) サーバーがデータの通過を確認すると、ハンドシェイクが正常に確立され、通常の暗号化データ通信が開始されます。
(2). セッション録画セッションチケット
(a) クライアントとサーバーの間で接続が確立されている場合、サーバーは暗号化された session_ticket 情報を new_session_ticket データに運び、クライアントはそれを保存します。
(b) クライアントがサーバーとの接続を再度確立する必要がある場合、暗号化された情報は client_hello の拡張フィールド session_ticket に入れられ、一緒にサーバーに送信されます。
(c) サーバーは session_ticket データを復号化しますが、復号化に失敗した場合は、通常のハンドシェイク プロセスが実行されます。
(d) 復号化が成功すると、change_cipher_spec および encrypted_handshake_message 情報が返されます。この 2 つの情報関数はセッション ID の関数と似ています。
(f) クライアントがサーバーによって暗号化されたデータを検証できる場合、クライアントは、change_cipher_spec および encrypted_handshake_message 情報も送信します。
(g) サーバーがデータの通過を確認すると、ハンドシェイクが正常に確立され、通常の暗号化データ通信が開始されます。
3. 接続を再確立します
接続再ネゴシエーションの再確立とは、使用中の TLS 接続を放棄し、ID 認証と鍵ネゴシエーションを再実行するプロセスであり、現在のデータ送信を切断することなく再認証、鍵またはアルゴリズムの更新ができるのが特徴です。サイドストレージとキャッシュ情報を維持できます。クライアントとサーバーの両方が接続を再確立するプロセスを開始できますが、現在、Windows 2000、XP、および SSL 2.0 はこれをサポートしていません。
(1).サーバーが接続を再確立します
サーバー側の再接続は通常、クライアントが保護されたデータにアクセスするときに発生します。基本的なプロセスは次のとおりです。
(a) 有効な TLS 接続が確立され、クライアントとサーバーの間で通信が行われます。
(b) 保護された情報へのクライアントのアクセス。
(c) サーバーは hello_request 情報を返します。
(d) hello_request メッセージを受信した後、クライアントは client_hello メッセージを送信し、接続の再確立を開始します。
(2).クライアントが接続を再確立する
クライアントは通常、通信キーを更新するために接続を再確立します。
(a) 有効な TLS 接続が確立され、クライアントとサーバーの間で通信が行われます。
(b) クライアントはキーを更新し、client_hello 情報を積極的に送信する必要があります。
(c) client_hello メッセージを受信した後、サーバーはメッセージがアプリケーション データではないことをすぐには認識できないため、次のステップに送信されて処理され、処理後、メッセージが接続の再確立を必要とするという通知が返されます。
(d) サーバーは、接続を再確立することが決定されるまで、クライアントへのデータの送信をすぐには停止しません。同時に停止することも、クライアントに送信する必要があるキャッシュされたデータがある場合でも、クライアントは停止する可能性があります。サーバーに情報を送信しません。
(e) サーバーは接続再確立要求を認識した後、server_hello メッセージをクライアントに送信します。
(f) クライアント側でも、その情報がアプリケーションデータではないとすぐに判断できないため、次の処理に送られ、処理後には、接続の再確立が必要であることを通知するために情報が返されます。
(g) クライアントとサーバーは、接続を再確立する新しいプロセスを開始します。
4. キーの計算
前のセクションでは、平文で送信される 2 つの乱数 randan_C および random_S と、暗号化によってサーバーとクライアント間で交換されるプリマスターについて説明しましたが、これら 3 つのパラメータが鍵共有の基礎となります。このセクションでは、鍵共有の基本的な計算プロセスと通信中の鍵の使用について説明します。
(1). キーの計算
パラメータには、ランダム クライアントとランダム サーバー、プレマスター、マスター シークレット、キー マテリアルが含まれます。キーを計算するとき、サーバーとクライアントの両方がこれらの基本情報を持ちます。交換方法は前のセクションで説明されており、計算プロセスは次のとおりです。以下に続きます:
(a) クライアントは、RSA や Diffie-Hellman などの暗号化アルゴリズムを使用してプレマスターを生成します。
(b) プレマスターは、ランダム クライアントとランダム サーバーの 2 つの乱数を組み合わせて、PseudoRandomFunction (PRF) を通じてマスター シークレットを計算します。
(c) マスターシークレットは、ランダムなクライアントとランダムなサーバーの 2 つの乱数を組み合わせて、反復計算を通じてキーマテリアルを取得します。
以下は、詳細な調査を行うのが好きな友人の疑問を解決する重要な記録です。資料をコピーして、皆さんと共有します。
(a) PreMaster シークレットの最初の 2 バイトは TLS バージョン番号です。これは、Client Hello フェーズ中にクライアントが暗号スイートのリストを送信し、現在サポートされているため、ハンドシェイク データをチェックするために使用されるより重要なバージョン番号です。 SSL/TLS バージョン番号はサーバーに与えられ、クリア テキストで送信されます。ハンドシェイク パケットがクラックされると、攻撃者はパケットを変更し、サーバーに対して安全性の低い暗号スイートとバージョンを選択する可能性が高くなります。データ。したがって、サーバーは、暗号文で復号化された PreMaster のバージョン番号と、前の Client Hello ステージのバージョン番号を比較する必要があります。バージョン番号が低くなった場合は、バージョン番号が変更されていることを意味し、メッセージの送信を直ちに停止します。(コピー)
(b) クライアントでもサーバーでも、生成される鍵が毎回同じにならないように乱数が必要です。SSL プロトコルの証明書は静的であるため、ネゴシエートされたキーのランダム性を保証するためにランダム要素を導入する必要があります。
RSA 鍵交換アルゴリズムの場合、プレマスター鍵自体は乱数に hello メッセージ内の乱数を加えたもので、最終的に 3 つの乱数は鍵エクスポーターを通じて対称鍵から導出されます。
プレマスターの存在は、SSL プロトコルが各ホストが完全にランダムな乱数を生成できることを信頼していないためです。乱数がランダムでない場合、プレマスターの秘密が推測される可能性があるため、プレマスターのみを使用するのは適切ではありません。マスター シークレットをキーとして使用します。したがって、新しいランダム要素を導入する必要があるため、クライアントとサーバーによって生成されたキーに加えて、プレマスター シークレットの 3 つの乱数を推測するのは容易ではありません。1 つの疑似乱数はまったくランダムではない可能性があります。しかし、3 つの擬似乱数 ランダム性はランダム性に非常に近く、自由度が 1 つ増えるごとに、ランダム性は 1 つ以上増加します。
(2).キーの使い方
12 ラウンドの反復計算の後、Key は 6 つの要素にグループ化された 12 個のハッシュ値を取得します。リストは次のとおりです。
(a) mac キー、暗号化キー、および IV は暗号化要素のセットで、それぞれクライアントとサーバーによって使用されますが、要素の両方のセットは両方の当事者によって同時に取得されます。
(b) クライアントはクライアント グループ要素を使用してデータを暗号化し、サーバーはクライアント要素を使用して復号化し、サーバーはサーバー要素を使用して暗号化し、クライアントはサーバー要素を使用して復号化します。
(c) 双方向通信の異なる方向で異なるキーが使用され、通信を解読するには少なくとも 2 回の試行が必要です。
(d) 暗号化キーはデータを対称的に暗号化するために使用されます。
(e) IV は多くの暗号化アルゴリズムの初期化ベクトルとして使用され、特に対称暗号化アルゴリズムを研究できます。
(f) Mac キーはデータの整合性の検証に使用されます。
(3).データ暗号化通信処理
(a) アプリケーション層データを適切なブロックにセグメント化します。
(b) リプレイ攻撃を防ぐために、断片化されたデータに番号を付けます。
(c) ネゴシエートされた圧縮アルゴリズムを使用してデータを圧縮します。
(d) MAC 値を計算し、データを圧縮して送信データを形成します。
(e) クライアント暗号化キーを使用してデータを暗号化し、サーバーに送信します。
(f) データを受信した後、サーバーはクライアント暗号化キーを使用してデータを復号化し、検証し、データを解凍し、再構築します。
注: MAC 値の計算には、クライアント Mac キーとハッシュ (番号、パケット タイプ、長さ、圧縮データ) という 2 つのハッシュ値が含まれます。
5. パケットキャプチャ分析
パケット キャプチャの詳細な分析は行いません。前の分析によると、基本的な状況は一致します。問題を特定する通常のプロセスに基づいて、注意が必要な点についていくつか述べたいと思います。
(1). HTTP通信をキャプチャすると、通信のヘッダーや情報の平文がはっきりとわかりますが、HTTPSは暗号化された通信なので、HTTPプロトコルのヘッダーやデータの平文はわかりません。
(2). パケットキャプチャ HTTPS 通信には主に TCP 接続確立、TLS ハンドシェイク、TLS 暗号化通信の 3 つのプロセスが含まれており、主にハンドシェイク確立と HTTPS 通信のステータス情報を分析します。
(3).client_hello
バージョン情報により、クライアントがサポートするプロトコルの最大バージョン番号を知ることができますが、SSL 3.0 や TLS 1.0 などのそれより低いバージョンのプロトコルの場合は、バージョンが低いためにハンドシェイクが失敗する可能性があることに十分注意してください。
SNI がサポートされているかどうかは、拡張フィールドの server_name フィールドに基づいて決定します。存在する場合はサポートされており、存在しない場合はサポートされていません。これは、ハンドシェイクの失敗や証明書の返送エラーを特定するのに非常に役立ちます。
セッション ID は標準プロトコルの一部です。接続が確立されていない場合、対応する値は空です。空でない場合は、対応する接続が以前に確立され、キャッシュされていることを意味します。
セッション レコード セッション チケット t は拡張プロトコル部分です。このフィールドの存在は、プロトコルがセッション チケットをサポートしていることを示します。それ以外の場合、サポートされていません。フィールドが存在し、値が空の場合は、接続が確立されていないことを意味しますそれが存在し、値が空でない場合は、キャッシュされた接続があることを意味します。
(4).server_hello
サーバーがサポートするプロトコルの最も高いバージョンは、TLS バージョン フィールドに基づいて推測できます。バージョンが異なるとハンドシェイクが失敗する可能性があります。
cipher_suite 情報に基づいて、サーバーがサポートする暗号化プロトコルを決定します。
(5).証明書
サーバーによって構成されて返された証明書チェーンは、証明書情報に従ってサーバー構成ファイルと比較され、要求が期待と一致するかどうかを判断し、一致しない場合はデフォルトの証明書を返すかどうかを判断します。
(6).アラート
アラーム情報アラートは、接続の確立に失敗した理由、つまりアラームの種類を説明します。これは問題を特定するために非常に重要です。