* Apache+openSSLでクライアント認証 [#a8f7da3a]
#setlinebreak(on);

#contents
-- 関連
--- [[クライアント認証付きのHTTPSリクエスト発行]]
--- [[Javaでhttps通信時の証明書検証について]]
--- [[ApacheでSSL(SNI)設定]]

** 手順 [#cceec743]
#html(<div style="padding-left:10px;">)

+ プライベートCAの作成
+ サーバ証明書の作成
+ クライアント証明書の作成
+ Apacheの設定変更

#html(</div>)

** プライベートCAの作成 [#f6bb94ec]
#html(<div style="padding-left:10px;">)

*** プライベートCA用のディレクトリなどを作成 [#p43ae54c]
#html(<div style="padding-left:10px;">)
#myterm2(){{
mkdir -p /var/certs/myCA
cd /var/certs/myCA
mkdir private
mkdir newcerts
chmod 700 private
echo 01>serial
touch index.txt
sudo openssl req -new -x509 -newkey rsa:2048 -out myca.crt -keyout private/myca.key -days 365 -sha256
・
いろいろ聞かれるので入力する
・
}}
#html(</div>)


*** openssl.cnf の作成 [#zbca8b9f]
#html(<div style="padding-left:10px;">)

オリジナルをコピーしてくる
#myterm2(){{
cd /var/certs
cp /etc/ssl/openssl.cnf ./
}}

以下の通り編集
/var/certs/openssl.cnf
#mycode2(){{
[ca]
default_ca    = my_ca_default
[my_ca_default]
new_certs_dir = ./myCA/newcerts
database      = ./myCA/index.txt
serial        = ./myCA/serial
policy        = my_ca_policy
default_md    = md5 
default_days  = 365 

[my_ca_policy]
commonName             = supplied
countryName            = optional
stateOrProvinceName    = optional
localityName           = optional
organizationName       = optional
organizationalUnitName = optional
emailAddress           = optional
}}

URLにIPアドレスを指定してアクセスする場合は、証明書の Subject Alternative Name もチェックされるので、これを含む証明書を作成する必要がある。
※作成方法は [[Javaでhttps通信時の証明書検証について]] を参照
#html(</div>)

#html(</div>)


** サーバ証明書の作成 [#t9e47755]
#html(<div style="padding-left:10px;">)

*** 鍵の作成 [#z4d5ea66]
#html(<div style="padding-left:10px;">)
#myterm2(){{
openssl genrsa -des3 -out example_com.key 1024
Generating RSA private key, 1024 bit long modulus
.++++++
...............++++++
e is 65537 (0x10001)
Enter pass phrase for example_com.key:
Verifying - Enter pass phrase for example_com.key:
}}
#html(</div>)

*** 鍵のパスフレーズを解除(Apache自動起動用) [#xae96aae]
#html(<div style="padding-left:10px;">)
#myterm2(){{
openssl rsa -in example_com.key -out example_com_nopass.key
Enter pass phrase for example_com.key:
writing RSA key
}}
#html(</div>)

*** 証明書への署名要求の作成 [#g6c248f7]
#html(<div style="padding-left:10px;">)
#myterm2(){{
openssl req -new -sha256 -key example_com.key -out example_com.csr
・
・
いろいろ聞かれるので入力する。
(注意)
Common Name、Organization Name は 実際のドメイン名と合わせておく事。(IPアドレスでアクセスする場合はIPアドレスをそのまま入力)
・
・
}}
#html(</div>)

*** プライベートCAで署名 [#s57aee41]
#html(<div style="padding-left:10px;">)
#myterm2(){{
sudo openssl ca -config ./openssl.cnf -md sha256 -cert myCA/myca.crt -keyfile myCA/private/myca.key -out example_com.crt -in example_com.csr
# IPアドレスでアクセスする場合は引数に -extensions v3_req も追加
#sudo openssl ca -config ./openssl.cnf -md sha256 -cert myCA/myca.crt -keyfile myCA/private/myca.key -out 192.168.1.10.crt -in 192.168.1.10.csr -extensions v3_req
・
・
Sign the certificate? [y/n]:y
1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated
}}
#html(</div>)


#html(</div>)


** クライアント証明書の作成 [#zd512cea]
#html(<div style="padding-left:10px;">)

基本的にはサーバ証明書と同じだが、署名時に使用する openssl.cnf を一部変更する必要がある。(下記参照)

*** 鍵の作成 [#g527d8a5]
#html(<div style="padding-left:10px;">)
#myterm2(){{
openssl genrsa -des3 -out example_com-client1.key 1024
Generating RSA private key, 1024 bit long modulus
.++++++
...............++++++
e is 65537 (0x10001)
Enter pass phrase for example_com.key:
Verifying - Enter pass phrase for example_com-client1.key:
}}
#html(</div>)

*** 証明書への署名要求の作成 [#a7e5eeb0]
#html(<div style="padding-left:10px;">)
#myterm2(){{
openssl req -new -sha256 -key example_com-client1.key -out example_com-client1.csr
・
いろいろ聞かれるので入力
・
}}
#html(</div>)

*** openssl.cnf を一部変更した openssl-client.cnf を作成 [#saaf2894]
#myterm2(){{

[my_ca_default]
.
.
x509_extensions = usr_cert     # 追加
.
.
[ usr_cert ]                                      # 追加
basicConstraints=CA:FALSE         # 追加
nsCertType = client, email            # 追加

}}

*** プライベートCAで署名( openssl-client.cnf を使用する事 ) [#v1c9261e]
#html(<div style="padding-left:10px;">)
#myterm2(){{
sudo openssl ca -config ./openssl-client.cnf -md sha256 -cert myCA/myca.crt -keyfile myCA/private/myca.key -out example_com-client1.crt -in example_com-client1.csr
・
・
Sign the certificate? [y/n]:y
1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated
}}
#html(</div>)


#html(</div>)


** Apacheの設定変更 [#jdcf88be]
#html(<div style="padding-left:10px;">)

*** 設定ファイル変更 [#h8e6d055]
#html(<div style="padding-left:10px;">)
#myhtml2(){{
<VirtualHost *:443>
    .
    .
    SSLCertificateFile /var/certs/example_com.crt
    SSLCertificateKeyFile /var/certs/example_com_nopass.key

    # プライベート認証局証明書のパス(クライアント証明書に署名したCA)
    SSLCACertificateFile /var/certs/myCA/myca.crt

    # クライアント証明書を要求する
    SSLVerifyClient require
    .
    .
</VirtualHost>
}}
#html(</div>)

*** 再起動 [#d0ac0942]
#html(<div style="padding-left:10px;">)
#myterm2(){{
sudo /usr/sbin/apachectl restart
}}
#html(</div>)

#html(</div>)


** 動作確認 [#wef7dbef]
#html(<div style="padding-left:10px;">)

#myterm2(){{
curl https://xxx.xxx.xxx/ --cacert /var/certs/myCA/myca.crt --key /var/certs/example_com-client1.key --cert /var/certs/example_com-client1.crt
}}

ただし curl が openSSL でビルドされてない場合は以下のように怒られる。
#myterm2(){{
curl: (58) SSL: Can't load the certificate "/var/certs/client1.crt" and its private key: OSStatus -25299」
}}

この場合は brew install curl --with-openssl で入れ直すか、クライアント証明書を PKCS#12 形式に変換する。
#myterm2(){{
openssl pkcs12 -export -in /var/certs/example_com-client1.crt -inkey /var/certs/example_com-client1.key -out /var/certs/example_com-client1.p12
}}

変換したP12形式の証明書を使用してリクエストする場合
#myterm2(){{
curl https://xxx.xxx.xxx/ --cacert /var/certs/myCA/myca.crt -E /var/certs/example_com-client1.p12:password
}}

#html(</div>)

トップ   差分 バックアップ リロード   一覧 単語検索 最終更新   ヘルプ   最終更新のRSS