ウェブブラウザのクライアント証明書 

いろいろ都合があってウェブブラウザのクライアント証明書を作ってみました。
以下手順です。
Linux(Gentoo)にOpenSSLとApache2を入れています。

まず認証局とサーバの証明書を作ります。

最初に乱数を作ります。

# cd /etc/apache2/conf/
# mkdir -p ssl
# cd ssl
# openssl dgst -md5 /etc/apache2/conf/* > rand.dat

認証局(CA)の秘密鍵を作ります。

# openssl genrsa -des3 -out ca.key -rand rand.dat 1024

入力したパスワード(パスフレーズ)は覚えておきましょう。

認証局の証明書を作ります。

# openssl req -new -x509 -days 365 -key ca.key -out ca.crt

認証局の秘密鍵のパスワードの入力が必要です。
認証局証明書とサーバ証明書の Organizational Unit Name が
同じだとエラーになるので気をつけてください。

サーバの秘密鍵を作ります。

# openssl genrsa -des3 -out server.key -rand rand.dat 1024

入力したパスワードは覚えておきましょう。

サーバの公開鍵を作ります。

# openssl req -new -key server.key -out server.csr

サーバの秘密鍵のパスワードの入力が必要です。
認証局証明書とサーバ公開鍵の Organizational Unit Name が
同じだとエラーになるので気をつけてください。
Common Name はサーバのホスト名(FQDN)を入力し、
A challenge password と An optional company name には何も入力しません。

サーバの秘密鍵からパスワードを削除します。

# cp server.key server.key.bak
# openssl rsa -in server.key.bak -out server.key

サーバの秘密鍵のパスワードの入力が必要です。

サーバの証明書を作ります。
http://www.modssl.org/source/ 等から落とした
mod_sslのソースに含まれている pkg.contrib/sign.sh を使います。

# ./sign.sh server.csr

認証局の秘密鍵のパスワードの入力が必要です。

生成されたものは "/etc/apache2/conf/ssl/" ディレクトリにコピーし、
apacheの設定ファイルに

SSLCACertificateFile conf/ssl/ca.crt

を追加します。

ではクライアント証明書を作成しましょう。

ファイル "/etc/ssl/openssl.cnf" の
[ CA_default ] セクションの dir を "./CA" に変更し、
先に作成した認証局の鍵をコピーします。

# cd /etc/ssl
# mkdir CA
# cd CA
# mkdir private
# cd private/
# cp /etc/apache2/conf/ssl/ca.key ./
# mv ca.key cakey.pem
# cd ..
# cp /etc/apache2/conf/ssl/ca.crt ./
# mv ca.crt cacert.pem
# cd ..

クライアント証明書要求を作成します。

# openssl req -new -keyout privatekey.pem -out privatecsr.pem

Organization Name は認証局証明書と同じにする必要があります。
Common Name は個人を特定する名前です。
また、入力したパスワードは覚えて置いてください。
A challenge password と An optional company name には何も入力しません。

クライアント証明書を作成します。

# openssl ca -out private_cert.pem -infiles privatecsr.pem

証明書の内容は

# openssl x509 -in private_cert.pem -text

で表示できます。

ブラウザにインポートするクライアント証明書を作成します。

# openssl pkcs12 -export -inkey privatekey.pem -in private_cert.pem -certfile ./CA/cacert.pem -name <名前> -out private_cert.p12

<名前>はクライアント証明書要求の Common Name です。
クライアント証明書要求のパスワードが必要です。
この証明書にパスワードを設定します。

生成した "private_cert.p12" を Google Chorme 等のウェブブラウザにインポートします。
インポートの際の先に設定したパスワードが必要です。

もしたくさんクライアント証明書が必要なら、
クライアント証明書要求から同一操作を行います。
ただし、”private_cert.pem”,”privatecsr.pem”,”privatekey.pem”,”private_cert.p12″のファイル名は
クライアント証明書毎に変更してください。

もし、”openssl req”の実行時に”newcerts”ディレクトリがないといわれたら

# mkdir /etc/ssl/CA/newcerts

で作成ください。また”index.txt”ファイルがないといわれたら

# touch /etc/ssl/CA/index.txt

で作成ください。さらに”serial”ファイルがないといわれたら

# echo 01 > /etc/ssl/CA/serial

で作成ください。
もし、”openssl ca”の実行時に

failed to update database
TXT_DB error number 2

のエラーが出た場合

# rm /etc/ssl/CA/index.txt
# touch /etc/ssl/CA/index.txt

を実行してからやり直してみてください。

apacheの設定ファイルで

SSLVerifyClient require

を設定すると、クライアント証明書を持たないクライアントからのアクセスを遮断します。

ちなみに、SSLの種類を制限するには、
"/etc/apache2/conf/modules.d/41_mod_ssl.default-vhost.conf"
の有効なところに
SSLProtocolディレクティブで設定できます。

SSLProtocol +SSLv3 +SSLv2 +TLSv1

とすればすべて受け入れ、ここで"+SSLv2"を抜けばSSLv2は拒否します。
変更後は

# /etc/init.d/apache2 restart

でウェブサーバの再起動が必要です。

ところで話は変わりますが、
"/etc/apache2/conf/apache2.conf"の最後に

SetEnv downgrade-1.0
SetEnv force-response-1.0

を入れると、http/1.1でリクエストしても
レスポンスがhttp/1.0になります。
変更後は再起動が必要です。