mutual TLS authentication

クライアント認証 (TLS)

[1] クライアント認証は、 TLSクライアントから TLSサーバークライアント証明書を送信することでサーバーにおいて認証を行う認証方式です。

[34] HTTPS で使われることが多いですが、それ以外でも TLS を使うアプリケーションで利用できます。

呼称

[56] TLS の機能であることを明確にするため、 TLSクライアント認証TLSクライアント証明書のようにいうことがあります。

[57] TLS は古くは SSL と呼ばれていました。未だに SSLクライアント認証SSLクライアント証明書のようにいうことがありますし、 SSL/TLSクライアント認証SSL/TLSクライアント証明書のようにいうことがあります。 厳密に言えば、 現在となっては SSL が使われることはまずありません。 SSL

プロトコル

[54] TLS では、 サーバーサーバー証明書クライアントを送信することになっていますが、 クライアントクライアント証明書を用意しなければならない義務はありません。 サーバーの求めがある時、クライアントクライアント証明書サーバーに送信します。

[55] サーバーは、クライアント証明書を検査して、 接続を継続するか、中断するか選択できます。 クライアント証明書がない場合や、 クライアント証明書が適切でない場合、 そのまま接続を継続することも選択できますし、 中断することもできます。 (サーバーの動作は、サーバーの実装や設定によって変わります。)

[41] TLSクライアント認証プロトコル

再折衝

[29] クライアント認証は、 TLS handshakeサーバーからの要求に応じてクライアントサーバーへと証明書を送信するものです。

[30] この TLS handshake は、 TLS を開始する最初のものであっても構いませんし、 その後の任意のタイミングで行っても構いません (再折衝)。

[31] Apachemod_sslHTTP 応答を返すに当たり、 ディレクトリーごとにクライアント認証の設定を行うことができます。 要求の処理の時点でそのディレクトリーに必要なクライアント証明書を受け取っていないことに気づいたら、 サーバークライアントに対して再折衝を求めます。 クライアントが適切な証明書を提示できれば、 サーバー応答を送ります。

[32] サーバーがどのようにクライアント認証を行うかはディレクトリーがわかるまで決められませんが、 どのディレクトリーへのアクセスなのかは HTTP要求を受信するまでわかりません。 HTTP要求を受信するためには最初の TLS handshake は終わっている必要があります。つまりこの Apache の方法を実現するには、 再折衝を使うしかありません。

[33] クライアント認証のための再折衝は、上位のプロトコルで適当なタイミング (HTTP要求を受信してHTTP応答を送る前など) で行われるのが普通ですが、 TLS と上位のプロトコルとの間でこのタイミングを調整する方法はないので、 それは保証されません。

>>27 のように扱いは実装によります。

[49] HTTP における扱いについては、 HTTPS を参照。

文脈

[2] 多くの Webブラウザーや、その他のHTTPS クライアントが対応しています。

[3] 公開された Webサイトでは滅多に使われませんが、組織内等のイントラネットWebアプリケーションではしばしば用いられています。

証明書

[58] TLSクライアント証明書のような言い方をしますが、 TLSクライアント認証に使われる証明書という、 利用目的を表す語です。

[59] TLSクライアント認証に適した形の証明書、 という条件は考えられなくもないですが、 特別に定められた技術的な絶対要件があるというものではありません。

[60] サーバー証明書として発行されたものをクライアント証明書として使うことも、 技術的には可能です。 (それに意味があるか、 使いやすいかどうかはまた別の問題です。)

証明書データベース

[13] 多くの Webブラウザー証明書データベースクライアント証明書秘密鍵 (およびルート証明書や必要があれば中間証明書) を保持しています。

[14] PKCS #12 などのファイルを手動で利用者が追加することもできますし、 keygen および証明書ダウンロードにより半自動で追加することもできます。 証明書データベース

[15] TLSクライアントは、サーバーからクライアント証明書を要求された場合、 その条件に該当する証明書が見つかればそれを送信します。

要求は CertificateRequest メッセージにより行います。 送信するべき証明書の条件もそこに記述されています。

[62] Webブラウザーダイアログを表示して適切な証明書利用者に選択させます (>>20)。 (自動選択させるオプションが用意されていることもあります。)

[63] その他のライブラリーやそれを使う専用のアプリケーションなどは、 それ以外のプログラム的な方法で証明書を選択するように設計されているかもしれません。 証明書データベース

[36] 実装上はクライアント証明書のことを個人証明書などと呼ぶようです。

ダイアログ

[20] Webブラウザークライアント証明書の求めがあると、 モーダルダイアログを表示します。これは初回の handshake だけでなく、 再折衝であってもです。ダイアログでは利用可能な証明書のリストか、 証明書なしを選ぶことができます。

[23] ただし利用できる証明書 (サーバーが指定した条件に合致する個人証明書) がまったくなければ、自動的に証明書なしとなります。

[22] Webブラウザー証明書の選択 (または無選択) を記憶しています。 Firefoxホスト名ごとに覚えているようです。 ChromeIEホスト名ポート番号の組ごとに覚えているようです。

[21] Firefox では、記憶させずにその場限りで選択するオプションがダイアログに表示されます。

[24] 一旦記憶させるとその後ずっと (認証失敗しても) 同じものを選択し続けます。

[25] Firefox ではサーバーから求められた「組織」と「発行者」がダイアログに表示されます。

[26] 選択後、まだ接続が有効なら、そのまま選択した証明書を使って処理を継続します。 接続が既に無効になっていれば、改めて接続します。そちらでサーバー証明書を要求して来れば、 記憶している選択された証明書を使います。

[27] ChromeHTTPヘッダー後の空行より前で再折衝があればダイアログを表示し、 それ以降ならネットワークエラーとして扱うようです。本体終了後なら無視するようです。 FirefoxIE本体終了後も含めてどこであってもダイアログを表示するようです。

[28] Firefox で選択を記憶させないようにすると、同じ要求の処理中の複数回の再折衝でもそれぞれダイアログを表示するように見えます。

他の認証方式との比較

[16] TLSクライアント認証利用者パスワードを入力させる必要がないという意味で安全な認証方式です。

[17] TLSクライアント認証証明書の管理が必要という点で、 利用者にとってはハードルが高いかもしれません。

[47] かつての keygen証明書ダウンロードを使うと利用者がほとんど意識することなく Webブラウザー証明書秘密鍵の管理を委ねられますが、 他の Webブラウザーを使ったり、他の装置上で動作する Webブラウザーを使ったりしたい時に、 証明書秘密鍵を安全に共有することは平均的な利用者には困難かもしれません。

[48] それ以外の場合、管理者と利用者の間で安全な方法で鍵と証明書の受け渡しを行い、 利用者Webブラウザーにインストールさせる必要がありますが、 これも平均的な利用者には難しい作業です。 ある程度の訓練を受けた管理者でないと、鍵の発行や管理と利用者の手引きも大変でしょう。


[18] HTTP認証 (基本認証など) やクッキー認証では、認証失敗時の HTTP応答アカウント登録パスワードの再発行などの回復手段を案内することができます。 しかし TLSクライアント認証TLS のセッション開始前に接続を閉じてしまうため、 同様の案内の機会がありません。 そのため Webブラウザーは一般的な認証エラーの表示しか行えません。

[19] 理論上はTLSサーバーは認証に失敗しても未認証状態で接続を継続し、 HTTP応答等の方法でエラーを伝えることはできます。しかしそのような利用方法が実際になされているのかどうかは不明です。

[35] Apache にはクライアント証明書を必須とするオプションの他に、 証明書の提示は求めるが必須とはしないオプションもあります。 証明書の有無により異なる応答を返すことにすれば、 認証エラーの表示を行えます。

[61] この不便が、クライアント認証が使われる場面が少ない理由の1つでもあります。 一方で、外部の者に案内すら晒さないことをむしろ好ましいとして採用する理由の1つにもなっています。

関連

[4] OAuth 2.0クライアント認証とは無関係です。

メモ

[5] RFC 4681 - TLS User Mapping Extension ( 版) http://tools.ietf.org/html/rfc4681

[6] Transport Layer Security (TLS) Parameters ( 版) http://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-14

CSV

table-tls-parameters-14-range

Range Registration Procedures

0-63 Standards Action

64-223 Specification Required

224-255 Reserved for Private Use

[7] Chrome 搭載デバイスのクライアント証明書を管理する - Chrome for Business ヘルプ ( 版) https://support.google.com/chrome/a/answer/6080885?hl=ja

[8] chrome.platformKeys - Google Chrome ( 版) https://developer.chrome.com/extensions/platformKeys

[9] chrome.enterprise.platformKeys - Google Chrome ( 版) https://developer.chrome.com/extensions/enterprise_platformKeys

[10] Developer Guide: Certificate Management Extension API on Chrome OS - The Chromium Projects ( 版) http://www.chromium.org/administrators/certificate-management-extension-api-on-chrome-os

[11] クライアント証明書の登録方法 | サイボウズ製品 マニュアルサイト ( 版) https://manual.cybozu.co.jp/tech/webbrowser/certificate.html

[12] draft-agl-tls-encryptedclientcerts-00 - Transport Layer Security (TLS) Encrypted Client Certificates ( 版) https://tools.ietf.org/html/draft-agl-tls-encryptedclientcerts-00

[37] RFC 6546 - Transport of Real-time Inter-network Defense (RID) Messages over HTTP/TLS ( 版) https://tools.ietf.org/html/rfc6546

RID systems MUST use mutual authentication; that is, both RID systems

acting as HTTPS clients and RID systems acting as HTTPS servers MUST

be identified by an X.509 certificate [RFC5280]. Mutual

authentication requires full path validation on each certificate, as

defined in [RFC5280].

[38] Keygen and Client Certificates ( 版) https://w3ctag.github.io/client-certificates/

[39] Fix #222: no credentials, no TLS client certificate · whatwg/fetch@bef06e1 ( 版) https://github.com/whatwg/fetch/commit/bef06e11e3b3b7589d23c0c892057c5cd5174c2a

[40] 21013 – Credentials and HTTP authentication ( 版) https://www.w3.org/Bugs/Public/show_bug.cgi?id=21013

[42] RFC 8075 - Guidelines for Mapping Implementations: HTTP to the Constrained Application Protocol (CoAP) () https://tools.ietf.org/html/rfc8075#section-10

An HC Proxy MUST implement Transport Layer Security (TLS) with a Pre-

Shared Key (PSK) [RFC4279] and SHOULD implement TLS [RFC5246] with

support for client authentication using X.509 certificates.

[43] RFC 8040 - RESTCONF Protocol () https://tools.ietf.org/html/rfc8040#section-2.5

To authenticate a client, a RESTCONF server SHOULD require

authentication based on TLS client certificates (Section 7.4.6 of

[RFC5246]). If certificate-based authentication is not feasible

(e.g., because one cannot build the required PKI for clients), then

HTTP authentication MAY be used.

[44] Web アプリの TLS 相互認証を構成する方法 | Microsoft Docs (naziml著, ) https://docs.microsoft.com/ja-jp/azure/app-service-web/app-service-web-configure-tls-mutual-auth

さまざまな種類の認証を有効にすることで、Azure Web アプリへのアクセスを制限できます。 これを行う 1 つの方法は、要求が TLS と SSL を経由するときに、クライアント証明書を使用して認証することです。 このメカニズムは、TLS 相互認証またはクライアント証明書認証と呼ばれます。

[45] Configuring TLS Mutual Authentication () http://docs.oracle.com/cd/E74890_01/books/Secur/secur_dataencrypt005.htm

In TLS mutual authentication, the client is authenticated to the server and the server is authenticated to the client during the TLS handshake, using digital certificates issued by certificate authorities.

[46] TLS Mutual Auth in GoLang – Bite-Code () http://www.bite-code.com/2015/06/25/tls-mutual-auth-in-golang/

[50] 775438 - Chrome sends TLS client certificates in CORS preflight, in violation of spec requirements - chromium - Monorail () https://bugs.chromium.org/p/chromium/issues/detail?id=775438

[51] /docs/man1.1.0/ssl/SSL_CTX_set_client_cert_cb.html (OpenSSL Foundation, Inc.著, ) https://www.openssl.org/docs/man1.1.0/ssl/SSL_CTX_set_client_cert_cb.html

[52] /docs/manmaster/man3/SSL_CTX_set_client_CA_list.html (OpenSSL Foundation, Inc.著, ) https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set_client_CA_list.html

[53] /docs/manmaster/man3/SSL_get_client_CA_list.html (OpenSSL Foundation, Inc.著, ) https://www.openssl.org/docs/manmaster/man3/SSL_get_client_CA_list.html