[1] クライアント認証は、 TLSクライアントから TLSサーバーへクライアント証明書を送信することでサーバーにおいて認証を行う認証方式です。
[34] HTTPS で使われることが多いですが、それ以外でも TLS を使うアプリケーションで利用できます。
[56] TLS の機能であることを明確にするため、 TLSクライアント認証、 TLSクライアント証明書のようにいうことがあります。
[57]
TLS は古くは SSL と呼ばれていました。未だに
SSLクライアント認証、
SSLクライアント証明書のようにいうことがありますし、
SSL/TLSクライアント認証、
SSL/TLSクライアント証明書のようにいうことがあります。
厳密に言えば、
現在となっては SSL
が使われることはまずありません。
[54] TLS では、 サーバーはサーバー証明書をクライアントを送信することになっていますが、 クライアントはクライアント証明書を用意しなければならない義務はありません。 サーバーの求めがある時、クライアントはクライアント証明書をサーバーに送信します。
[55] サーバーは、クライアント証明書を検査して、 接続を継続するか、中断するか選択できます。 クライアント証明書がない場合や、 クライアント証明書が適切でない場合、 そのまま接続を継続することも選択できますし、 中断することもできます。 (サーバーの動作は、サーバーの実装や設定によって変わります。)
[29] クライアント認証は、 TLS handshake でサーバーからの要求に応じてクライアントがサーバーへと証明書を送信するものです。
[30] この TLS handshake は、 TLS を開始する最初のものであっても構いませんし、 その後の任意のタイミングで行っても構いません (再折衝)。
[31] Apache の mod_ssl は HTTP 応答を返すに当たり、 ディレクトリーごとにクライアント認証の設定を行うことができます。 要求の処理の時点でそのディレクトリーに必要なクライアント証明書を受け取っていないことに気づいたら、 サーバーはクライアントに対して再折衝を求めます。 クライアントが適切な証明書を提示できれば、 サーバーは応答を送ります。
[32] サーバーがどのようにクライアント認証を行うかはディレクトリーがわかるまで決められませんが、 どのディレクトリーへのアクセスなのかは HTTP要求を受信するまでわかりません。 HTTP要求を受信するためには最初の TLS handshake は終わっている必要があります。つまりこの Apache の方法を実現するには、 再折衝を使うしかありません。
[33] クライアント認証のための再折衝は、上位のプロトコルで適当なタイミング (HTTP要求を受信してHTTP応答を送る前など) で行われるのが普通ですが、 TLS と上位のプロトコルとの間でこのタイミングを調整する方法はないので、 それは保証されません。
[2] 多くの Webブラウザーや、その他のHTTPS クライアントが対応しています。
[3] 公開された Webサイトでは滅多に使われませんが、組織内等のイントラネット系 Webアプリケーションではしばしば用いられています。
[58] TLSクライアント証明書のような言い方をしますが、 TLSクライアント認証に使われる証明書という、 利用目的を表す語です。
[59] TLSクライアント認証に適した形の証明書、 という条件は考えられなくもないですが、 特別に定められた技術的な絶対要件があるというものではありません。
[13] 多くの Webブラウザーは証明書データベースにクライアント証明書と秘密鍵 (およびルート証明書や必要があれば中間証明書) を保持しています。
[14] PKCS #12 などのファイルを手動で利用者が追加することもできますし、 証明書ダウンロードにより半自動で追加することもできます。
keygen
および
[15] TLSクライアントは、サーバーからクライアント証明書を要求された場合、 その条件に該当する証明書が見つかればそれを送信します。
[62] Webブラウザーはダイアログを表示して適切な証明書を利用者に選択させます (>>20)。 (自動選択させるオプションが用意されていることもあります。)
[63]
その他のライブラリーやそれを使う専用のアプリケーションなどは、
それ以外のプログラム的な方法で証明書を選択するように設計されているかもしれません。
[20] Webブラウザーはクライアント証明書の求めがあると、 モーダルダイアログを表示します。これは初回の handshake だけでなく、 再折衝であってもです。ダイアログでは利用可能な証明書のリストか、 証明書なしを選ぶことができます。
[23] ただし利用できる証明書 (サーバーが指定した条件に合致する個人証明書) がまったくなければ、自動的に証明書なしとなります。
[22] Webブラウザーは証明書の選択 (または無選択) を記憶しています。 Firefox はホスト名ごとに覚えているようです。 Chrome と IE はホスト名とポート番号の組ごとに覚えているようです。
[21] Firefox では、記憶させずにその場限りで選択するオプションがダイアログに表示されます。
[24] 一旦記憶させるとその後ずっと (認証失敗しても) 同じものを選択し続けます。
[25] Firefox ではサーバーから求められた「組織」と「発行者」がダイアログに表示されます。
[26] 選択後、まだ接続が有効なら、そのまま選択した証明書を使って処理を継続します。 接続が既に無効になっていれば、改めて接続します。そちらでサーバーが証明書を要求して来れば、 記憶している選択された証明書を使います。
[27] Chrome はHTTPヘッダー後の空行より前で再折衝があればダイアログを表示し、 それ以降ならネットワークエラーとして扱うようです。本体終了後なら無視するようです。 Firefox と IE は本体終了後も含めてどこであってもダイアログを表示するようです。
[28] Firefox で選択を記憶させないようにすると、同じ要求の処理中の複数回の再折衝でもそれぞれダイアログを表示するように見えます。
[16] TLSクライアント認証は利用者にパスワードを入力させる必要がないという意味で安全な認証方式です。
[17] TLSクライアント認証は証明書の管理が必要という点で、 利用者にとってはハードルが高いかもしれません。
[47] かつての keygen
と証明書ダウンロードを使うと利用者がほとんど意識することなく
Webブラウザーに証明書と秘密鍵の管理を委ねられますが、
他の Webブラウザーを使ったり、他の装置上で動作する Webブラウザーを使ったりしたい時に、
証明書と秘密鍵を安全に共有することは平均的な利用者には困難かもしれません。
[48] それ以外の場合、管理者と利用者の間で安全な方法で鍵と証明書の受け渡しを行い、 利用者の Webブラウザーにインストールさせる必要がありますが、 これも平均的な利用者には難しい作業です。 ある程度の訓練を受けた管理者でないと、鍵の発行や管理と利用者の手引きも大変でしょう。
[18] HTTP認証 (基本認証など) やクッキー認証では、認証失敗時の HTTP応答でアカウント登録やパスワードの再発行などの回復手段を案内することができます。 しかし TLSクライアント認証は TLS のセッション開始前に接続を閉じてしまうため、 同様の案内の機会がありません。 そのため Webブラウザーは一般的な認証エラーの表示しか行えません。
[35] Apache にはクライアント証明書を必須とするオプションの他に、 証明書の提示は求めるが必須とはしないオプションもあります。 証明書の有無により異なる応答を返すことにすれば、 認証エラーの表示を行えます。
[61] この不便が、クライアント認証が使われる場面が少ない理由の1つでもあります。 一方で、外部の者に案内すら晒さないことをむしろ好ましいとして採用する理由の1つにもなっています。
[4] OAuth 2.0クライアント認証とは無関係です。
[5] RFC 4681 - TLS User Mapping Extension ( 版) http://tools.ietf.org/html/rfc4681
[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
[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
[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