今や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のアプリで利用するように指定してみました。社内コンプライアンスに従うためとはいえ、調査や試行錯誤で動作するまで時間を費やしてしまいました。証明書は奥が深いですね。