SSLでハンドシェイクが成功しない場合、常にハンドシェイクアラートで終了しますか?
またはSSL接続を終了する他の方法があります(標準で受け入れられます)。
これは、クライアント認証を要求するように構成されたHTTPSサーバーで、クライアントが証明書を送信しない場合、サーバーからクライアントに(ネットワークパケットを介して)TLS完了メッセージが表示されるためです。警告を期待していた。
SSL/TLSconnectionは常に何らかの種類のアラートメッセージで終了する必要があります。切断された接続(たとえば、基になるTCPソケットは閉じられています)アラートがなければ、不適切に終了したと言います。正常終了のアラートメッセージはclose_notify
。
handshakeは接続の一部にすぎません。開始時にハンドシェイクが発生し、後続のハンドシェイクを同じ接続で再生できます。ハンドシェイクは通常、エラーが発生してアラートメッセージがトリガーされる場所ですが、致命的なアラートメッセージはハンドシェイクだけを終了するのではなく、接続全体を閉じます。
クライアント認証を要求するサーバーの場合、クライアントは、証明書を送信して署名を計算することで応答します。ただし、これはオプションです。クライアントは要求を受け入れないようにすることができます。次に、サーバーは実行する処理を選択します。サーバーは、接続を閉じる警告メッセージを介して、クライアントをすぐに拒否します。サーバーは、続行することを決定し、クライアント認証の欠如を別のレベルで処理することもできます。 Finished
メッセージを送信するサーバーは、続行することを選択します。おそらく、サーバーはエラーをトンネル内のアプリケーションデータとして報告することを決定する可能性があります(たとえば、HTTPSサーバーの場合、[〜#〜] http [〜#〜]ハンドシェイクが終了するとエラーメッセージが表示されます)。
詳細は RFC 2246 、セクション7.4.6を参照してください。
This is the first message the client can send after receiving a
server hello done message. This message is only sent if the
server requests a certificate. If no suitable certificate is
available, the client should send a certificate message
containing no certificates. If client authentication is required
by the server for the handshake to continue, it may respond with
a fatal handshake failure alert.
→「5月」を強調。
TLS 1.0仕様(RFC 2246)のクライアント証明書に関するセクション は次のように述べています。
適切な証明書がない場合、クライアントは証明書を含まない証明書メッセージを送信する必要があります。ハンドシェイクを続行するためにサーバーでクライアント認証が必要な場合、クライアント認証は、致命的なハンドシェイク失敗アラートで応答することがあります。
それが致命的な警告で応答する可能性があるという事実は、応答する必要があることを意味するものではありません。
質問にIISのタグを付けましたが、ここに他のサーバーに関する背景を少し説明します。 Apache Httpdには クライアント証明書を要求するための3つの設定 :none
、optional
およびrequired
(およびoptional_no_ca
そこで証明書の検証を無効にしたい)。サーバーがoptional
で構成されている場合、クライアントが証明書を提示しなくても、ハンドシェイクは続行されます。サーバーがrequired
で構成されている場合、クライアント証明書がないと、致命的なハンドシェイクエラーアラートが発生します。 Javaの SSLEngine
は、これらの設定をsetWantClientAuth
およびsetNeedClientAuth
で実装します。
ハンドシェイクを続行しても、サーバーがリソースへのアクセスを許可したり、リクエストの実行を承認したりするわけではありません。
致命的なハンドシェイク失敗アラート動作の大きな欠点は、接続が突然閉じられることです。せいぜい、ブラウザでは「接続が閉じました-ハンドシェイクの失敗」メッセージ(または類似のメッセージ)として表示されます。 HTTP交換はまったく行われないため、問題を説明するためにHTTPステータスコードや付随するWebページを送信する機会はありません。
ユーザビリティの観点から、これは特にクライアント証明書に必ずしも精通していないユーザーにとっては非常に混乱する可能性があります(多くの場合、証明書を処理するための特定の学習曲線があります)。このため、多くのサーバーはオプションのクライアント証明書認証のみを必要とし、認証が拒否された場合に説明を送信できるようにします。
IISの設定に完全に精通しているわけではないことを認めなければなりませんが、 ドキュメント には3つのオプションがあることも示唆されているようです。
クライアントが証明書を提示してもクライアント証明書を受け入れたくない場合は、「無視」を選択します。
Acceptを選択して、クライアント証明書を受け入れます。
[必須]を選択して、クライアント証明書を要求します。 「クライアント証明書が必要」を使用するには、「SSLが必要」を有効にする必要があります。
別のドキュメント は、必要な証明書の提供に失敗した場合のHTTPステータスコードとエラーメッセージがあることを示唆しています:「403.7禁止:クライアント証明書が必要です」。この場合のHTTPステータスコードがあるという事実は、それがハンドシェイクエラーの原因ではないことを意味します(そうでない場合、接続が確立されず、HTTPメッセージを送信できません)。これは、IISの "require"モードが、TLSハンドシェイクに関する限り、Apache Httpdの "optional"モードのように動作すること、つまり、クライアント証明書を提示しないことが原因ではないことを意味します致命的な警告(もちろん、承認は別の問題です)。
では、「無視する」と「受け入れる」の意味がわかりません。 SSL/TLSでは、CertificateRequest
メッセージを送信して、サーバーのみが証明書を要求できます。サーバーがこのメッセージを送信しない場合、クライアントはRFC 2246からの証明書を再び送信することはありません。
7.4.6。クライアント証明書
このメッセージが送信されるタイミング:これは、サーバーのハロー完了メッセージを受信した後にクライアントが送信できる最初のメッセージです。このメッセージは、サーバーが証明書を要求した場合にのみ送信されます。
私の推測では、アカウントマッピングまたは承認に関して、「無視する」/「受け入れる」ことを意味します。
EDIT。
私が覚えている限り、デフォルトでは、IISは常にre-negotiationを使用してクライアント証明書をネゴシエートします):最初のハンドシェイクはクライアントなしで成功します-certificateリクエストが送信された後、2番目のハンドシェイクがトリガーされます。これは、この2番目のハンドシェイクが暗号化されたセッション内で行われるため、パケットを見てもクライアント証明書の交換を確認できないことを意味します(場合によっては、Wiresharkを使用して、サーバーの秘密鍵で構成され、暗号スイートをサポートします)。
netsh のclientcertnegotiation=enable
オプションを使用して、クライアント証明書のネゴシエーションが初期ハンドシェイク内で実行されるように構成できます(これは初期ハンドシェイクを参照します)。
Apacheで使用されているOpenSSLの例を取り上げます。
SSL_VERIFY_PEERと呼ばれるモードフラグがあり、サーバーで設定されると、ハンドシェイク時にクライアント証明書を要求します。クライアントはそれを自由に送信できます。
次に、サーバーの動作は別のフラグに依存します。
SSL_VERIFY_FAIL_IF_NO_PEER_CERT
これは次のように説明されています
サーバーモード:クライアントが証明書を返さなかった場合、TLS/SSLハンドシェイクは「ハンドシェイクエラー」アラートで即座に終了します。このフラグは、SSL_VERIFY_PEERと一緒に使用する必要があります。
このフラグが設定されていない場合、アラートは作成されず、ハンドシェイクは通常どおり続行され、サーバーは後で証明書を確認し、必要に応じて接続を閉じる必要があります。
編集:IIS 7.0の同様の構成オプションに関する詳細情報:
https://www.iis.net/ConfigReference/system.webServer/security/access
次のいずれかである可能性があるsslFlags属性があるようです
SslRequireCertの代わりにSslNegotiateCertが構成されているため、気付く動作が発生すると思います。