keytoolでWebSphere Liberty用の鍵ストアとトラストストアを作成する

WebSphere Libertyが使用する証明書をデフォルトの自己署名証明書の有効期限は1年だが、有効期限が10年のものを作成したい。`securityUtility`コマンドで鍵ストアを作成してみたところ、バージョン19.0.0.3から鍵ストアの形式がjks形式からp12形式に変わっており、また、`securityUtility`コマンドではトラストストアを作る方法がわからなかったため、`keytool`コマンドでのやり方を確認したメモ。

なお、Libertyのserver.xmlでのトラストストアの指定はオプションで、指定がない場合は鍵ストアとして指定したものが使用される。

## keytool

カレントディレクトリをマウントしてLibertyのコンテナを実行し、コンテナ内でファイルを作成したあと、マウントしたディレクトリーにファイルをコピーして取り出す。

```:コマンド
# Libertyコンテナを実行して中に入る
docker run --rm -it -u 0 -v $PWD:/work websphere-liberty:19.0.0.4-kernel bash
# マウントしたディレクトリーに移動
cd /work
# 鍵ストアを作成し、鍵ペアと自己署名証明書を作成して格納
keytool -genkeypair -v -keystore key.jks \
　-alias default \
  -keyalg RSA \
  -keysize 2048 \
  -validity 36500
# 鍵ストアの内容の確認
keytool -list -v -keystore key.jks
# 鍵ストアから証明書を取り出す
keytool -exportcert -keystore key.jks -alias default -file default.der
# （オプション）derをpemに変換
openssl x509 -inform DER -outform PEM -in default.der -out default.pem
# トラストストアを作成し、証明書を格納（どちらの形式でもOK）
keytool -importcert -keystore trust.jks -alias default -file default.pem
# keytool -importcert -keystore trust.jks -alias default -file default.der
# トラストストアの内容の確認
keytool -list -v -keystore trust.jks
# コンテナを抜ける
exit
```

```shell-session:実行例
$ docker run --rm -it -u 0 -v $PWD:/work websphere-liberty:19.0.0.4-kernel bash
root@c3c1748ca862:/# cd work
root@c3c1748ca862:/work# keytool -genkeypair -v -keystore key.jks \
> -alias default \
>   -keyalg RSA \
>   -keysize 2048 \
>   -validity 36500
Enter keystore password:
Re-enter new password:
What is your first and last name?
  [Unknown]:  localhost
What is the name of your organizational unit?
  [Unknown]:
What is the name of your organization?
  [Unknown]:
What is the name of your City or Locality?
  [Unknown]:
What is the name of your State or Province?
  [Unknown]:
What is the two-letter country code for this unit?
  [Unknown]:
Is CN=localhost, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown correct? (type "yes" or "no")
  [no]:  yes

Generating 2,048 bit RSA key pair and self-signed certificate (SHA256WithRSA)
	for: CN=localhost, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown
Enter key password for <default>:
	(RETURN if same as keystore password):
New certificate (self-signed):
[
[
  Version: V3
  Subject: CN=localhost, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown
  Signature Algorithm: SHA256withRSA, OID = 1.2.840.113549.1.1.11

  Key:  IBMJCE RSA Public Key:
modulus:
19650360791731354008116518642233444279579249915742369282788593522525615438372245864339191426427166450868581201815037776142025680976800822760272268896874462078144731638543558726297833937432689474867624315943089899216401866304295908519485588682659265567905096740045639225540018428547581701932992611902924686429471394412703541561719211411123644446931927616282213987565134887357844236865677513550355779361184577857528239765256170746803056204548053317837849221057635973150268000518814516972295731253752598643498765003499459223670333261667981975313887417291194849261181529465429865339459030987997550430970787074648389925847
public exponent:
65537

  Validity: [From: Wed May 08 10:41:55 UTC 2019,
               To: Fri Apr 14 10:41:55 UTC 2119]
  Issuer: CN=localhost, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown
  SerialNumber: [1955447027]

Certificate Extensions: 1
[1]: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: a8 e4 e5 a9 8a 30 fe 57  a4 eb a0 66 b3 5d d1 54  .....0.W...f...T
0010: 48 20 9d f9                                        H...
]
]

]
  Algorithm: [SHA256withRSA]
  Signature:
0000: 17 73 a5 3f 3c 53 2e cd  69 1a c5 97 dd a7 f1 c6  .s...S..i.......
0010: d4 3a 36 1d e7 3c 0c 79  6c 87 da 93 84 8f 93 a8  ..6....yl.......
0020: a9 68 aa aa 39 e4 b7 20  fb 73 3f 2d 9a a7 42 b8  .h..9....s....B.
0030: 90 18 02 cb 9b de 1c 33  0f 1e 8b 22 dd ce 2d dc  .......3........
0040: fa 5e e9 8e 73 e2 9a ce  6b 22 3b a9 b5 49 c8 9a  ....s...k....I..
0050: 0e d9 a1 b5 1c af 4b bd  a8 02 f6 7b d4 f8 0a 1b  ......K.........
0060: b5 b6 fb 6b 20 db ef 9b  6f 43 6c ed c2 9b fc 32  ...k....oCl....2
0070: 0e 9f 68 54 c0 0f 9b 3b  eb 36 a0 4f 31 62 ef 89  ..hT.....6.O1b..
0080: e4 3b 5d ec 85 70 34 d8  2a 45 40 95 13 11 d8 c9  .....p4..E......
0090: 3d a0 17 3b b9 7f 68 74  52 5a 76 a8 2a aa bd 36  ......htRZv....6
00a0: 79 01 bc af 0c 88 bd 90  9b 73 69 21 b7 c7 e7 34  y........si....4
00b0: e2 6c f5 03 10 85 a2 96  fe 5d 21 fb 3f 7b 46 eb  .l............F.
00c0: f4 a5 9b 63 45 ef ae 47  7b 5e 85 b5 d4 2d f0 14  ...cE..G........
00d0: 98 84 fd 80 3a c1 6f 53  af c0 60 1e 9a d6 cc f1  ......oS........
00e0: 4a 22 64 a7 c0 85 ff 36  6e 4a 12 2e 5d b7 5a 4b  J.d....6nJ....ZK
00f0: d5 14 c4 6d d8 da 7d 3e  c5 d4 50 a4 1d d8 4b 55  ...m......P...KU

]
[Storing key.jks]
root@c3c1748ca862:/work# keytool -list -v -keystore key.jks
Enter keystore password:

Keystore type: jks
Keystore provider: IBMJCE

Your keystore contains 1 entry

Alias name: default
Creation date: May 8, 2019
Entry type: keyEntry
Certificate chain length: 1
Certificate[1]:
Owner: CN=localhost, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown
Issuer: CN=localhost, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown
Serial number: 748dc0f3
Valid from: 5/8/19 10:41 AM until: 4/14/19 10:41 AM
Certificate fingerprints:
	 MD5:  60:60:3C:BD:5A:51:1F:B5:CC:9D:4C:06:24:66:2E:33
	 SHA1: C7:79:4C:10:DC:47:71:97:70:22:AF:27:73:05:83:77:00:78:B1:25
	 SHA256: 43:DB:96:1F:02:0E:D7:ED:63:9B:93:C5:D9:2D:65:57:FB:3E:BD:1E:B9:5A:C5:51:4D:E7:F7:C7:6F:CF:99:9A
	 Signature algorithm name: SHA256withRSA
	 Version: 3

Extensions:

#1: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: a8 e4 e5 a9 8a 30 fe 57  a4 eb a0 66 b3 5d d1 54  .....0.W...f...T
0010: 48 20 9d f9                                        H...
]
]



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


root@c3c1748ca862:/work# keytool -exportcert -keystore key.jks -alias default -file default.der
Enter keystore password:
Certificate stored in file <default.der>
root@c3c1748ca862:/work# openssl x509 -inform DER -outform PEM -in default.der -out default.pem
root@c3c1748ca862:/work# keytool -importcert -keystore trust.jks -alias default -file default.pem
Enter keystore password:
Re-enter new password:
Owner: CN=localhost, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown
Issuer: CN=localhost, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown
Serial number: 748dc0f3
Valid from: 5/8/19 10:41 AM until: 4/14/19 10:41 AM
Certificate fingerprints:
	 MD5:  60:60:3C:BD:5A:51:1F:B5:CC:9D:4C:06:24:66:2E:33
	 SHA1: C7:79:4C:10:DC:47:71:97:70:22:AF:27:73:05:83:77:00:78:B1:25
	 SHA256: 43:DB:96:1F:02:0E:D7:ED:63:9B:93:C5:D9:2D:65:57:FB:3E:BD:1E:B9:5A:C5:51:4D:E7:F7:C7:6F:CF:99:9A
	 Signature algorithm name: SHA256withRSA
	 Version: 3

Extensions:

#1: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: a8 e4 e5 a9 8a 30 fe 57  a4 eb a0 66 b3 5d d1 54  .....0.W...f...T
0010: 48 20 9d f9                                        H...
]
]

Trust this certificate? [no]:  yes
Certificate was added to keystore
root@c3c1748ca862:/work# keytool -list -v -keystore trust.jks
Enter keystore password:

Keystore type: jks
Keystore provider: IBMJCE

Your keystore contains 1 entry

Alias name: default
Creation date: May 8, 2019
Entry type: trustedCertEntry

Owner: CN=localhost, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown
Issuer: CN=localhost, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown
Serial number: 748dc0f3
Valid from: 5/8/19 10:41 AM until: 4/14/19 10:41 AM
Certificate fingerprints:
	 MD5:  60:60:3C:BD:5A:51:1F:B5:CC:9D:4C:06:24:66:2E:33
	 SHA1: C7:79:4C:10:DC:47:71:97:70:22:AF:27:73:05:83:77:00:78:B1:25
	 SHA256: 43:DB:96:1F:02:0E:D7:ED:63:9B:93:C5:D9:2D:65:57:FB:3E:BD:1E:B9:5A:C5:51:4D:E7:F7:C7:6F:CF:99:9A
	 Signature algorithm name: SHA256withRSA
	 Version: 3

Extensions:

#1: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: a8 e4 e5 a9 8a 30 fe 57  a4 eb a0 66 b3 5d d1 54  .....0.W...f...T
0010: 48 20 9d f9                                        H...
]
]



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


root@c3c1748ca862:/work# exit
exit
$ ls -l
total 32
-rw-r--r--  1 sotoiwa  staff   897  5  8 19:42 default.der
-rw-r--r--  1 sotoiwa  staff  1269  5  8 19:42 default.pem
-rw-r--r--  1 sotoiwa  staff  2251  5  8 19:41 key.jks
-rw-r--r--  1 sotoiwa  staff   961  5  8 19:43 trust.jks
$
```

## securityUtility

securityUtilityコマンドで鍵ストアを作成する場合は以下のようにする。

```shell:コマンド
# Libertyコンテナを実行して中に入る
docker run --rm -it -u 0 -v $PWD:/work websphere-liberty:19.0.0.4-kernel bash
# 鍵ストアを生成
/opt/ibm/wlp/bin/securityUtility createSSLCertificate \
  --server=defaultServer \
  --password=wasadmin \
  --keySize=2048 \
  --sigAlg=SHA256withRSA \
  --subject=CN=localhost \
  --validity=36500
# 鍵ストアをマウントしたディレクトリーにコピー
cp /opt/ibm/wlp/output/defaultServer/resources/security/key.p12 /work
# 鍵ストアの内容の確認
keytool -list -v -storetype pkcs12 -keystore /work/key.p12
# コンテナを抜ける
exit
```

```shell-session:実行例
$ docker run --rm -it -u 0 -v $PWD:/work websphere-liberty:19.0.0.4-kernel bash
root@00a51bf1b028:/# /opt/ibm/wlp/bin/securityUtility createSSLCertificate \
>   --server=defaultServer \
>   --password=wasadmin \
>   --keySize=2048 \
>   --sigAlg=SHA256withRSA \
>   --subject=CN=localhost \
>   --validity=36500
Creating keystore /opt/ibm/wlp/output/defaultServer/resources/security/key.p12

Created SSL certificate for server defaultServer. The certificate is created with CN=localhost as the SubjectDN.

Add the following lines to the server.xml to enable SSL:

    <featureManager>
        <feature>ssl-1.0</feature>
    </featureManager>
    <keyStore id="defaultKeyStore" password="{xor}KD4sPjsyNjE=" />


root@00a51bf1b028:/# cp /opt/ibm/wlp/output/defaultServer/resources/security/key.p12 /work
root@00a51bf1b028:/# keytool -list -v -storetype pkcs12 -keystore /work/key.p12
Enter keystore password:

Keystore type: pkcs12
Keystore provider: IBMJCE

Your keystore contains 1 entry

Alias name: default
Creation date: May 8, 2019
Entry type: keyEntry
Certificate chain length: 1
Certificate[1]:
Owner: CN=localhost
Issuer: CN=localhost
Serial number: 2d4ca1dd
Valid from: 5/8/19 10:45 AM until: 4/14/19 10:45 AM
Certificate fingerprints:
	 MD5:  8B:B9:11:E8:A9:37:5F:D2:E4:FF:69:BC:B7:61:84:3D
	 SHA1: DF:BE:03:C3:C3:2F:97:4B:5D:82:48:4E:E5:EF:0E:77:E0:73:C7:7A
	 SHA256: F3:FE:06:77:8A:26:90:2F:DA:54:EE:2B:32:69:08:34:47:82:AD:3C:73:60:7C:4B:42:EE:D6:91:00:3D:07:C8
	 Signature algorithm name: SHA256withRSA
	 Version: 3

Extensions:

#1: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: 19 04 f3 0a 07 55 c9 1b  4d d6 29 db a7 41 c4 ed  .....U..M....A..
0010: 50 91 4b 18                                        P.K.
]
]



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


root@00a51bf1b028:/# exit
exit
$ ls -l
total 8
-rw-r--r--  1 sotoiwa  staff  2529  5  8 19:46 key.p12
$
```

## 参考リンク

- [JDK keytool の基本的な使い方 (openssl との対比)](https://www.qoosky.io/techs/9db75cec15)
- [コマンド行からの SSL 証明書の作成](https://www.ibm.com/support/knowledgecenter/ja/SSEQTP_liberty/com.ibm.websphere.wlp.doc/ae/twlp_sec_create_certificate.html)
- [SSL 構成の属性](https://www.ibm.com/support/knowledgecenter/ja/SSEQTP_liberty/com.ibm.websphere.wlp.doc/ae/rwlp_ssl.html)
- [OpenSSLによるオレオレ認証局が署名した証明書の作成](https://qiita.com/sotoiwa/items/35f42d969210e0fcd62e)