2021/10/19

SSL/TLS証明書の作成

今やWebアクセスにはSSL/TLSの考慮は必須の時代となりました。私が所属する会社では、TLS対応していない通信はITから許可されません。検証用のJava Webアプリケーション(Spring Boot)を公開するために証明書を作成する必要がありました。本記事は、証明書作成の備忘録となります。


自己署名証明書の作成

Javaをインストールしている場合は、keytoolというコマンドが利用できます。またLinux OSではopensslコマンドで証明書の作成ができます。


証明書の生成

Windows上からkeytoolコマンドを用いて証明書を作成してみます。ここでは、パスワードには"password"を指定しています。

keytool -genkeypair -alias testcert -keyalg RSA -keysize 2048 -storetype PKCS12 -keystore testcert.p12 -validity 3650

Enter keystore password:
Re-enter new password:
What is your first and last name?
  [Unknown]:  Taro Yamada
What is the name of your organizational unit?
  [Unknown]:  Sales Engineering
What is the name of your organization?
  [Unknown]:  Test Company
What is the name of your City or Locality?
  [Unknown]:  Tokyo
What is the name of your State or Province?
  [Unknown]:
What is the two-letter country code for this unit?
  [Unknown]:  JP
Is CN=Taro Yamada, OU=Sales Engineering, O=Test Company, L=Tokyo, ST=Unknown, C=JP correct?
  [no]:  yes


証明書の確認

生成した証明書の内容を確認します。

keytool -list -v -keystore testcert.p12

Enter keystore password:
Keystore type: PKCS12
Keystore provider: SUN

Your keystore contains 1 entry

Alias name: testcert
Creation date: Apr 22, 2021
Entry type: PrivateKeyEntry
Certificate chain length: 1
Certificate[1]:
Owner: CN=Taro Yamada, OU=Sales Engineering, O=Test Company, L=Tokyo, ST=Unknown, C=JP
Issuer: CN=Taro Yamada, OU=Sales Engineering, O=Test Company, L=Tokyo, ST=Unknown, C=JP
Serial number: 19cd4d7b
Valid from: Thu Apr 22 15:52:28 JST 2021 until: Sun Apr 20 15:52:28 JST 2031
Certificate fingerprints:
         SHA1: BC:EC:5B:07:56:B4:ED:E8:26:8F:69:8D:95:32:C5:72:97:88:04:A8
         SHA256: 10:66:2A:8D:AE:A1:3D:92:47:E1:74:49:5D:05:FC:52:00:BE:70:31:58:34:50:63:29:0F:70:8B:46:16:20:80
Signature algorithm name: SHA256withRSA
Subject Public Key Algorithm: 2048-bit RSA key
Version: 3

Extensions:

#1: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: DE 79 F4 00 7C 90 52 5D   D2 F9 45 85 4C 0C 95 29  .y....R]..E.L..)
0010: EA 1A 52 FD                                        ..R.
]
]

*******************************************
*******************************************


Spring Bootプロジェクトの設定

プロジェクトのresourcesフォルダに、先ほど作成したkeystoreファイル(証明書)を配置します。

Application.ymlを作成(既存のApplication.propertiesでもOK)にTLSの設定を追加します。

server:
  ssl:
    key-store: classpath:testcert.p12
    key-store-password: password
    key-store-type: pkcs12
    key-alias: testcert
  port: 8443


デバッグ起動すると、htttp://localhost:8443/xxxでアクセスできました。その際、信頼されていない証明書のため、警告もでますね。取り急ぎ、動作OKということです。


正式版証明書の作成

その後、ITと話した結果、やっぱり自己証明書では外部公開できないとのこと。そうですよね・・・最初から言ってよ。ということでCSRの生成から正式版証明書を作成することになりました。

IT管理のプロキシサーバで、SSL/TLSインスペクションで通信管理をするとのことです。複合できるように会社のルート証明書に遡れる証明書でないとダメですよね・・・


CSRの生成

今度はopensslコマンドで証明書を作成してみましょう。Webアプリケーションコンテナを稼働させる予定のLinuxサーバ上で実施しました。

sudo openssl genrsa -out webappserver.key 2048
Generating RSA private key, 2048 bit long modulus (2 primes)
..................................+++++
..+++++
e is 65537 (0x010001)
sudo openssl req -new -key webappserver.key -out webappserver.csr
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
State or Province Name (full name) [Some-State]:Tokyo
Locality Name (eg, city) []:Chiyoda-ku
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Test Company
Organizational Unit Name (eg, section) []:Sales Engineering
Common Name (e.g. server FQDN or YOUR name) []:webappserver
Email Address []:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:


ITで署名

ITチームにCSRとパスワード情報を提供します。その結果、署名済み証明書(certnew.cer)と中間証明書込みの証明書(certnew.p7b)を入手しました。


Javaキーストアの作成

P7b形式のまま取り扱うのは困難なため、PEM形式に変換(certnew.p7b → certificate-chain.cer)します。

openssl pkcs7 -inform der -in certnew.p7b -out certificate-chain-temp.cer
openssl pkcs7 -print_certs -in certificate-chain-temp.cer -out certificate-chain.cer


PEMファイルに秘密鍵をインポートして、12ファイルを生成(certificate-chain.cer + webappserver.key → webappserver.p12)します。ここではパスワードは"password"です。

openssl pkcs12 -export -in certificate-chain.cer -inkey webappserver.key -name webappserver -out webappserver.p12
Enter Export Password: password
Verifying - Enter Export Password: password


次に、P12ファイルを元に、testcert.jksという名前のJavaキーストアを作成(webappserver.p12 → testcert.jks)します。

keytool -importkeystore -deststorepass password -destkeystore testcert.jks -srckeystore webappserver.p12 -srcstoretype PKCS12
Importing keystore webappserver.p12 to testcert.jks...
Enter source keystore password:
Entry for alias webappserver successfully imported.
Import command completed:  1 entries successfully imported, 0 entries failed or cancelled


Javaキーストア(testcert.jks)の内容を確認します。中間証明書とTLS用の証明書が含まれているようです。

keytool -list -v -keystore testcert.jks
Enter keystore password:
Keystore type: PKCS12
Keystore provider: SUN

Your keystore contains 1 entry

Alias name: webappserver
Creation date: ***
Entry type: PrivateKeyEntry
Certificate chain length: 2
Certificate[1]:
Owner: CN=webappserver, OU=Sales Engineering, O=Test Company, L=Chiyoda-ku, ST=Tokyo, C=JP
Issuer: CN=***-CA, DC=***, DC=***
Serial number: ***
Valid from: *** until: ***
Certificate fingerprints: ***
Signature algorithm name: ***
Subject Public Key Algorithm: ***
Version: ***

Extensions:

#1: ObjectId: ***
***
:

Certificate[2]:
Owner: CN=***-CA, DC=***, DC=***
Issuer: ***
Serial number: ***
Valid from: *** until: ***
Certificate fingerprints: ***
Signature algorithm name: ***
Subject Public Key Algorithm: ***
Version: ***

Extensions:

#1: ObjectId: ***
:

*******************************************
*******************************************


Spring Bootプロジェクトの設定

Application.ymlにTLSの設定を追加します。

server:
  ssl:
    key-store: classpath:testcert.jks
    key-store-password: password
    key-store-type: pkcs12
    key-alias: testcert
  port: 8443


おわりに

証明書の生成を行い、Java Spring Bootのアプリで利用するように指定してみました。社内コンプライアンスに従うためとはいえ、調査や試行錯誤で動作するまで時間を費やしてしまいました。証明書は奥が深いですね。