SSL:クライアント認証


サーバの公開鍵を第三者(CA)の秘密鍵で署名してもらうことで、サーバ・クライアント間の接続の確実性が向上します。
ヨッパサーバは貧乏サーバのために、本来、第三者へ依頼しなければならないサーバ公開鍵への署名も自身で行いました。
個人運営の実験サーバなので、これで十分だと考えます。

この仕組みで、クライアントからは、サーバを信頼できる相手と認識できます。
しかし、サーバから見たクライアントは、信頼できる相手と確信できるのでしょうか?
クライアントの信頼性を確保する手段として、パスワードによる認証が一般的です。
しかし、この方法は、クライアントがパスワードを盗まれれば終わりです。

さらに安全性を高めるためにクライアント認証による方法があります。
ここでは、このクライアント認証の設定方法を解説します。

クライアント認証の流れ


クライアント認証は、次に示す流れで行われます。



  1. クライアントは、サーバへhttps接続
  2. サーバはクライアントに、クライアント証明書を要求
  3. クライアントは、クライアント証明書をサーバへ送付
  4. そのとき、クライアント証明書をユーザが選択する
  5. サーバは署名されたクライアント証明書を解読しクライアントの公開鍵を取得
  6. クライアントは、送付メッセージにダイジェストを付加し、クライアントの持つ秘密鍵で暗号化する
  7. サーバは、クライアントの公開鍵を使ってメッセージを解読
  8. 解読したメッセージからメッセージ・ダイジェストを作成し、クライアントが付加したメッセージ・ダイジェストと比較する
  9. 一致が確認されれば、信頼できるクライアントから改ざんされていないメッセージを受信したと言える

クライアント証明書の作成


クライアント証明書は、WindowsPCに設定します。
その場合 PKCS#12 フォ-マットにする必要があります
PKCS(Public Key Cryptography Standard) 米RSA Security社が定義した公開鍵暗号技術を利用のための規格

筆者は規格の詳しいところは分かりません。
しかし、、PKCS#12フォーマットのファイルを作成するには、秘密鍵と署名要求の両方が記述されているファイルが必要です。
パラメータは、下記のように -keyout(秘密鍵ファイル) と -out(署名要求ファイル) のファイル名を同じ名前にして実行します。
# openssl req -new -keyout alk_client_key.pem -out alk_client_key.pem ←秘密鍵と証明書要求の作成
Generating a 1024 bit RSA private key
..................++++++
...................................++++++
writing new private key to 'alk_client_key.pem'
Enter PEM pass phrase:  ←クライアント秘密鍵のパスフレーズを入力
Verifying - Enter PEM pass phrase: ←確認の為上記と同じパスフレーズを入力
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:JP ←国コード(JP)を入力
State or Province Name (full name) [Some-State]:Osaka ←都道府県名を入力
Locality Name (eg, city) []:HigashiOsaka ←市町村名を入力
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Arkland ←会社名
Organizational Unit Name (eg, section) []: ←所属名を入力
Common Name (eg, YOUR name) []:alk ←名前を入力
Email Address []: ←メールアドレスを入力

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []: ←何も入力しない
An optional company name []: ←何も入力しない

秘密鍵と署名要求の入った、alk_client_key.pemが作成されています。
このファイルを使って、秘密鍵に署名します。
このときに、Netscapeを使う可能性のある場合は、次の変更をする必要があります。
変更ファイル名:/etc/ssl/openssl.cnf
[ usr_cert ]
# nsCertType =  client, email
(コメントを外す)
nsCertType =  client, email

証明機関(CA)は自身で構築したものを使用します。

# cd /etc/ssl
# openssl ca -policy policy_anything -out ./key/alk_client_csr.pem -infiles ./key/alk_client_key.pem ←CAに署名を要求
Using configuration from /usr/lib/ssl/openssl.cnf
Enter pass phrase for ./alkCA/private/cakey.pem: ←CAのパスフレーズを入力
DEBUG[load_index]: unique_subject = "yes"
Check that the request matches the signature
Signature ok
Certificate Details:
        Serial Number: 4 (0x4)
        Validity
            Not Before: Apr 22 05:38:31 2005 GMT
            Not After : Apr 22 05:38:31 2006 GMT
        Subject:
            countryName = JP
            stateOrProvinceName = Osaka
            localityName = HigashiOsaka
            organizationName = Arkland
            commonName = alk
        X509v3 extensions:
            X509v3 Basic Constraints:
                CA:FALSE
            Netscape Comment:
                OpenSSL Generated Certificate
            X509v3 Subject Key Identifier:
                BC:A6:D7:05:F5:09:83:E2:71:2B:63:8F:A6:CA:71:98:8F:8D:2C:A5
            X509v3 Authority Key Identifier:
                keyid:2E:32:D3:46:58:9B:81:87:2E:F6:07:71:13:55:35:F4:63:0E:83:7D
                DirName:/C=JP/ST=Osaka/L=HigashiOsaka/O=Arkland/CN=alk.dip.jp
                serial:F1:1E:D4:B3:25:07:A1:E1

Certificate is to be certified until Apr 22 05:38:31 2006 GMT (365 days)
Sign the certificate? [y/n]:y ←yを入力


1 out of 1 certificate requests certified, commit? [y/n]y ←yを入力
Write out database with 1 new entries
Data Base Updated
alk_client_key.pem へ署名した alk_client_csr.pem が作成されます

秘密鍵(alk_client_key.pem)と署名された秘密鍵(alk_client_csr.pem)からPKCS#12形式のファイルを作成します。
# cd /etc/ssl/key
# openssl pkcs12 -export -clcerts -inkey alk_client_key.pem -in alk_client_csr.pem -out alk_client.p12
Enter pass phrase for alk_client_key.pem: ←秘密鍵のパスフレーズを入力
Enter Export Password: ←PKCS#12形式の証明書を取り出すときのパスフレーズを入力
Verifying - Enter Export Password: ←上記と同じパスワードを入力
alk_client.p12 がPKCS#12形式のファイルです。
openssl での操作はここまでです。

Apache2の設定


SSLサイトの設定は、下記ファイルで定義しています。
詳しくは、ここを参照。
設定ファイル /etc/apache2/sites-available/ssl

このファイルに次の2行の記述を追加します。
追加行 意味
SSLCACertificateFile /etc/ssl/alkCA/cacert.pem CAの証明書の場所
SSLVerifyClient require 接続にはクライアント認証を必須とする

この後Apache2を再起動させます。
/etc/init.d/apache2 restart
Apache2側の設定は以上です。

ブラウザの設定


opensslで作成した alk_client.p12 をクライアントPCへ持ってきます。
alk_client.p12ファイルをダブルクリックすることでインストールを開始します。

<alk_client.p12ファイルをダブルクリック>




<[次へ]でファイルの選択>




<[次へ]でパスフレーズの入力>




<[次へ]でパスワードの入力>




<[完了]をクリック>


以上で、クライアント認証によるSSLサイトへの接続が可能になります。