代表的な面接トピック

TLS 1.3のハンドシェイク後クライアント認証はいつ使用すべきか?

一般難しい
Offer.cc 編集チーム公開日 更新日

質問

長時間存続するサービスにおいて、最初にTLS 1.3を確立し、特定のリクエストに対してのみクライアント証明書を要求したいと考えています。前提条件、メッセージフロー、障害ポリシー、セッション再開時の影響、および検証計画を説明してください。

プロンプトとコンテキスト

長時間存続する管理用接続を運用しています。ほとんどのリクエストではクライアント証明書の処理を避ける必要がありますが、高リスクな操作ではクライアントを識別しなければなりません。TLS 1.3のハンドシェイク後クライアント認証を設計し、初期ハンドシェイク時の相互TLS(mTLS)と比較した境界を説明してください。

面接官がテストしていること

回答では、ハンドシェイク後認証を2つ目のTLS接続としてではなく、TLS 1.3のオプションのメッセージフローとして扱う必要があります。初期ClientHelloでのクライアントによるpost_handshake_auth機能のアドバタイズ、その後のサーバーによるCertificateRequestの送信、クライアントによる証明書チェーンおよびCertificateVerifyの返送、障害処理、ならびにその結果のHTTP/2、HTTP/3、またはアプリケーションリクエストへのバインドについて網羅してください。

最初に確認すべき明確化のための質問

認証のスコープ

認証が接続ごとに1回なのか、高リスクリクエストごとに1回なのか、それともテナントに依存するのかを確認します。キャッシュ期間が長すぎると失効ウィンドウが拡大し、要求頻度が高すぎると証明書検証コストやプロトコルメッセージが増加します。

プロトコルと実装の境界

接続がHTTP/1.1、HTTP/2、HTTP/3、またはカスタムプロトコルのいずれを伝送しているか、およびTLSライブラリがハンドシェイク後APIを公開しているかを確認します。アプリケーションは認証が完了するまで保護された操作をブロックしなければなりません。

障害および失効ポリシー

証明書の期限切れ、未知のCA、不正な署名、または未サポートの機能が発生した場合に、単一のリクエストを拒否するのか、接続を切断するのか、低権限セッションを維持するのかを定義します。OCSP、短期間証明書、または失効リストのソースを特定します。

30秒の回答フレームワーク

「TLS 1.3のハンドシェイク後認証では、クライアントが初期ClientHelloでpost_handshake_authをアドバタイズする必要があります。サーバーは後からCertificateRequestを送信し、クライアントはCertificate、CertificateVerify、およびFinishedを返します。サーバーはチェーン、用途、署名、失効状態を検証した上で、そのアイデンティティを以降のリクエストにバインドします。機能がネゴシエートされていない場合や検証に失敗した場合、ポリシーは暗黙的にダウングレードするのではなく、保護された操作を拒否するか接続を切断する必要があります。」

ステップバイステップの詳細な回答

ステップ 1: 機能をネゴシエートし、未認証の暗号化セッションを作成する

クライアントはClientHelloでサポートをアドバタイズします。サーバーは通常のTLS 1.3ハンドシェイクを完了しますが、接続を暗号化済みかつクライアント未認証としてマークします。機能をアドバタイズしなかったクライアントに対して後から証明書の提示を要求することはできません。ポリシーに従って低権限にルーティングするか、再接続させます。

ステップ 2: ポリシーが必要とするときにCertificateRequestを送信する

高リスクなエンドポイントまたはテナントポリシーがアイデンティティを要求する場合、サーバーは許容可能な署名アルゴリズムと認証局制約を含めたCertificateRequestを送信します。TLSステートマシンは、並行ストリームが中途半端に更新された状態を観測しないよう、これをアプリケーションの書き込みとシリアライズ(順序付け)しなければなりません。

ステップ 3: クライアントのレスポンスを検証する

クライアントは証明書チェーン、CertificateVerify、およびFinishedを送信します。チェーン、SANまたはURIアイデンティティ、キー用途、署名アルゴリズム、有効期間、および失効を検証します。その後初めて、アイデンティティ、証明書フィンガープリント、認証時刻を接続コンテキストに関連付けます。それより前に到着した機密性の高いリクエストはキューイングするか拒否する必要があります。

ステップ 4: 障害とリトライを処理する

サポートされていない機能、証明書の欠落、無効な署名、または失効については、アプリケーションエラーを返すか、TLSアラートを送信するか、ポリシーに従って切断します。リトライは回数と時間で制限します。失敗した高リスクリクエストを自動的に匿名リクエストに変換してはなりません。秘密鍵情報や不要な証明書コンテンツを含めずに、エラー分類と設定バージョンをログに記録します。

ステップ 5: セッション再開、並行性、および移行を考慮する

セッション再開は、現在のアプリケーション認可が依然として有効であることを自動的に証明するものではありません。再開された接続ではポリシーを再評価します。HTTP/2の多重化では、他のストリームがリクエストを送信している間に1つのストリームが認証をトリガーする可能性があるため、ブロックの境界を定義します。HTTP/3 QUIC/TLS実装がこのメッセージフローをサポートしていることを確認してから採用を決定してください。

ステップ 6: 信頼と鍵マテリアルを運用する

専用のクライアントCA、短期間証明書、および監査可能なトラストストアの展開を使用します。CAローテーション中は二重信頼ウィンドウとロールバックパスを維持します。サーバー秘密鍵、トラストストア、ポリシー公開の権限を分離します。クライアント検証によってサーバー鍵操作へのアクセス権が付与されてはなりません。

ステップ 7: テストと可観測性

機能を持つクライアントと持たないクライアントのテストマトリクスを構築します。成功、期限切れ証明書、不正な署名、失効、タイムアウト、並行ストリーム、およびセッション再開をテストします。CertificateRequestのレート、成功率、障害分類、認証レイテンシ、拒否された保護リクエスト、および接続切断を監視します。テストログに秘密鍵や機密ペイロード全体が露出しないようにします。

高品質な回答サンプル

私は「暗号化済みだが未認証」と「クライアント認証済み」の2つの状態をモデル化します。サーバーがCertificateRequestを送信できるようになる前に、クライアントはClientHelloでpost_handshake_authをアドバタイズする必要があります。クライアントはチェーン、CertificateVerify、およびFinishedを返し、サーバーはCA、SAN、用途、署名、有効期間、および失効を確認した上で、アイデンティティを高リスクリクエストにバインドします。

機能がネゴシエートされていない場合や検証が失敗した場合は、保護された操作を拒否し、暗黙的にダウングレードしないようにします。認証保留中は保護されたHTTP/2ストリームを凍結し、HTTP/3に対するライブラリのサポートを検証します。セッション再開後は認可を再評価します。クライアントマトリクスを用いてロールアウトし、開始、成功、失敗理由、レイテンシ、および失効の動作を監視します。

よくある間違い

  • 間違い: 接続が確立されていることはクライアントが認証されていることを意味するとみなす。 → 失敗の理由: 暗号化とクライアントアイデンティティは別個の状態です。 → 修正方法: 両方の状態を明示的に追跡する。
  • 間違い: 機能をネゴシエートしなかったクライアントに証明書を要求する。 → 失敗の理由: 機能は初期ClientHelloでアドバタイズされなければなりません。 → 修正方法: 低権限ポリシーまたは再接続ポリシーを使用する。
  • 間違い: 認証失敗後にリクエストを実行する。 → 失敗の理由: 認証メッセージは非同期に到着するため、過去に遡って処理を保護することはありません。 → 修正方法: 検証が完了するまで保護されたストリームをブロックする。
  • 間違い: 新しいテナント認可に古い接続アイデンティティを再利用する。 → 失敗の理由: セッション再開やポリシー変更によって古いアプリケーション状態が無効になる可能性があります。 → 修正方法: 認可バージョンを使用して再評価する。

フォローアップの質問と回答

フォローアップ 1: なぜ初期の相互TLSが今でも一般的なのですか?

初期の相互TLSはハンドシェイクが終了する前にアイデンティティを選択および検証するため、すべてのリクエストで認証が必要な場合、その状態管理と互換性の面でよりシンプルです。ハンドシェイク後認証は、より多くの状態管理と並行性ルールのコストを伴いますが、ごく一部の操作のみに追加のアイデンティティが必要な長時間接続に適しています。

フォローアップ 2: アプリケーション認可を置き換えることはできますか?

いいえ。これは秘密鍵の所持と有効な証明書チェーンを証明するだけです。アプリケーションは依然としてSAN、テナント、ロール、操作、および失効状態を認可決定にマッピングし、その決定バージョンを記録する必要があります。

フォローアップ 3: 証明書を持たないクライアントは必ず切断しなければなりませんか?

必ずしもそうではありません。ポリシーによっては、低権限セッションを維持し、保護されたリクエストのみを拒否することもできます。継続的な認証を必要とする管理プレーンの場合は、明確なエラーを返して切断すべきです。その選択を監査可能かつ観測可能にしてください。

フォローアップ 4: ライブラリがこのフローをサポートしていることをどのように証明しますか?

拡張機能ネゴシエーション、CertificateRequest、無効な証明書、並行ストリーム、およびセッション再開に関するバージョニングされたAPIと相互運用性テストを確認します。単一の設定フラグだけでは、ステートマシン全体が実装されていることの証明にはなりません。

公開情報ソース

関連する質問