理系学生日記

おまえはいつまで学生気分なのか

HTTPS双方向認証の環境を作る

以下のエントリで HTTPS 通信を試してみましたが、このような試験環境を作るのはわりとメンドい。 メンドいことを何度もやりたくないので、実施した内容をエントリに残しておきます。

クライアント認証を含めた HTTPS の双方向認証を行うためには、以下が必要になります。

  1. CA の作成
  2. サーバ証明書の作成
  3. クライアント証明書の作成
  4. HTTPS に対応したサーバの立ち上げ
  5. (Java の場合) KeyStore、TrustStore の作成

CA を作成する

CA が使用する秘密鍵を作成した後、証明書を作成するかたちになります。

# CA が使用する秘密鍵を ca.key として作成する
$ openssl genrsa -out ca.key 2048
# CA の証明書を ca.crt として作成する
$ openssl req -new -x509 -days 3650 -key ca.key -out ca.crt -subj '/CN=kiririmode CA'

サーバ証明書を作成する

サーバ証明書の作成には、CSR を作成した上で、CA に署名してもらえば良いです。

# サーバ証明書用の CSR を作成する
$ openssl genrsa -out server.key 2048
$ openssl req -new -key server.key -out server.csr -subj '/CN=server.kiririmode.com'

# CA に CSR に署名してもらい、サーバ証明書 (server.crt) を作成する
$ openssl x509 -req -days 3650 -CA ca.crt -CAkey ca.key -CAcreateserial -in server.csr -out server.crt

クライアント証明書を作成する

ここでは 2 つ作成してみます。やってることはサーバ証明書と同じですね。

$ openssl genrsa -out client1.key 2048
$ openssl req -new -key client1.key -out client1.csr -subj '/CN=com.kiririmode.client1'
$ openssl x509 -req -days 3650 -CA ca.crt -CAkey ca.key -CAcreateserial -in client1.csr -out client1.crt

$ openssl genrsa -out client2.key 2048
$ openssl req -new -key client2.key -out client2.csr -subj '/CN=com.kiririmode.client2'
$ openssl x509 -req -days 3650 -CA ca.crt -CAkey ca.key -CAcreateserial -in client2.csr -out client2.crt

HTTPS に対応したサーバの立ち上げ

せっかく openssl を使っているのであれば、openssl にサーバも任せてしまえば良いです。以下の 1 行だけで、HTTPS サーバが立ち上がります。 -Verify はクライアント証明を必須とするオプションです。

$ openssl s_server -accept 14433 -cert server.crt -key server.key -Verify 5 -CAfile ./ca.crt -www -debug

(Javaの場合)KeyStore、TrustStore の作成

KeyStore の作成については注意すべき点があって、クライアント証明書を keytool でそのままインポートしたとしても、秘密鍵の情報が KeyStore に格納されない。 これを何とかするためには、一度 X.509 の証明書と鍵を PKCS12 形式に変換してやってから、keytool でインポートする。

$ openssl pkcs12 -export -in client1.crt -inkey client1.key -out client1.p12 -name client1 -CAfile ca.crt -caname ca
$ keytool -importkeystore -destkeystore keystore.ks -srckeystore client1.p12 -srcstoretype PKCS12 -srcstorepass password -alias client1

$ openssl pkcs12 -export -in client2.crt -inkey client2.key -out client2.p12 -name client2 -CAfile ca.crt -caname ca
$ keytool -importkeystore -destkeystore keystore.ks -srckeystore client2.p12 -srcstoretype PKCS12 -srcstorepass password -alias client2

TrustStore については、単に作れば良いんじゃないですかね。

$ keytool -import -keystore truststore.ks -file ca.crt     -alias kiririmodeca
$ keytool -import -keystore truststore.ks -file server.crt -alias server

参考: How to import an existing X.509 certificate and private key in Java keystore to use in SSL? - Stack Overflow