はじめに (対象読者・この記事でわかること)
このページは、Javaで SSL/TLS 通信を行う際に必要となる JKS 形式のキーストアを、ローカル環境および CI/CD パイプラインで自動生成できるようになることを目的としています。対象読者は、Java 開発経験はあるが、証明書の管理やキーストア操作に不安があるエンジニア、またはインフラ担当者です。この記事を読むことで、自己署名証明書の作成方法、keytool と openssl を組み合わせた実践的な手順、よくあるエラーとその対処法を具体的に把握でき、ローカル開発環境やテスト環境で即座に SSL 設定が行えるようになります。
前提知識
- Java の基本的な開発環境(JDK がインストールされていること)
- コマンドライン操作に慣れていること(
bash/PowerShell) - HTTPS/SSL の概念(証明書、秘密鍵、公開鍵)の概要を理解していること
JKSキーストアの概要と背景
Java では、TLS/SSL の証明書や秘密鍵を格納する際に「キーストア」と呼ばれるコンテナを使用します。JKS(Java KeyStore)はその標準フォーマットであり、java.security.KeyStore API で直接扱える点が大きな特徴です。JKS が好まれる理由は次の通りです。
-
Java 標準対応
keytoolだけで作成・管理でき、外部ライブラリの導入が不要です。これにより、開発環境から本番環境まで一貫した運用が可能です。 -
パスワード保護
キーストア全体にパスワードを設定できるため、ファイル単体が盗まれても内容が暗号化されます。 -
エイリアスによる管理
複数の証明書や鍵を「エイリアス」という名前で区別でき、アプリケーション側で柔軟に参照できます。
しかし、実務では多くの場合、外部の CA(認証局)から取得した証明書は PEM 形式(*.crt、*.key)で提供されます。このままでは JKS に直接インポートできないため、openssl で PEM を PKCS12 に変換し、さらに keytool で JKS に変換する二段階の手順が一般的です。以下では、この変換フローを具体的に示し、スクリプト化できる形まで落とし込みます。
JKSキーストア作成の実践手順
本セクションでは、自己署名証明書を生成し、keytool と openssl を組み合わせて JKS キーストアを作成するフローを解説します。実際にターミナルで入力すべきコマンド例と、スクリプト化したサンプルコードを掲載します。
ステップ 1 – 秘密鍵と自己署名証明書の作成
まずは openssl で RSA 鍵ペアと自己署名証明書(X.509)を生成します。以下のコマンドは、2048 ビット鍵と有効期間 365 日の証明書を作成します。
Bash# 秘密鍵の生成 openssl genrsa -out server.key 2048 # 証明書署名要求 (CSR) の作成 openssl req -new -key server.key -out server.csr -subj "/C=JP/ST=Tokyo/L=Shibuya/O=ExampleCorp/OU=IT/CN=example.local" # 自己署名証明書の発行 openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt
ポイント
--subjで省略可能な属性を一行で指定すると、対話式入力を省けます。
- 本番環境では自己署名ではなく、認証局から発行された証明書を使用してください。
ステップ 2 – PEM から PKCS12 への変換
JKS にインポートできる形式は PKCS12(.p12)です。秘密鍵と証明書を 1 つの PKCS12 コンテナにまとめます。
Bashopenssl pkcs12 -export \ -in server.crt \ -inkey server.key \ -name myserver \ -out server.p12 \ -passout pass:changeit
-nameは PKCS12 内のエイリアスです。後で JKS にインポートするときに同じ名前が使用されます。-passoutで PKCS12 に設定するパスワードを指定します。サンプルではchangeitとしていますが、実際は強度の高いパスワードに変更してください。
ステップ 3 – PKCS12 から JKS へのインポート
keytool を使って PKCS12 を JKS に変換します。
Bashkeytool -importkeystore \ -deststorepass changeit \ -destkeypass changeit \ -destkeystore keystore.jks \ -srckeystore server.p12 \ -srcstoretype PKCS12 \ -srcstorepass changeit \ -alias myserver
-deststorepassと-destkeypassは JKS のパスワードです。-aliasで指定したエイリアスは、アプリケーション側でSSLContextに設定するときに使用します。
ステップ 4 – JKS の内容確認
作成したキーストアに正しくエントリが入っているか確認します。
Bashkeytool -list -v -keystore keystore.jks -storepass changeit
このコマンドで、証明書のサブジェクトや有効期限、エイリアス名が表示されます。期待した情報が出力されていれば、キーストアは正しく構築されています。
ハマった点やエラー解決
1. keytool が「Keystore password was incorrect」エラーを出す
- 原因:
openssl pkcs12 -export時に指定したパスワードと、keytool -importkeystore時に指定した-srcstorepassが一致していないケースが多いです。 - 対策:両方のコマンドで同一のパスワードを使用するか、環境変数に一時的に保存して統一的に参照します。
2. 証明書チェーンが欠如している
- 原因:自己署名証明書だけを PKCS12 に入れた場合、クライアントが信頼できるルート証明書として認識しないことがあります。
- 対策:中間証明書やルート証明書がある場合は、
-certfileオプションで追加し、PKCS12 に含めます。
Bashopenssl pkcs12 -export \ -in server.crt \ -inkey server.key \ -certfile intermediate.crt \ -name myserver \ -out server.p12 \ -passout pass:changeit
3. JKS が「Alias already exists」エラーを出す
- 原因:同一エイリアスが既にキーストアに存在する。
- 対策:
-aliasを新しい名前に変えるか、keytool -delete -alias <alias> -keystore keystore.jksで既存エントリを削除してから再インポートします。
スクリプト化サンプル
以下は、上記手順を Bash スクリプトにまとめた例です。CI パイプラインで実行すれば、毎回同一の JKS を自動生成できます。
Bash#!/usr/bin/env bash set -euo pipefail # 設定項目(必要に応じて変更) KEY_ALIAS="myserver" KEYSTORE_PASS="changeit" KEY_SIZE=2048 VALID_DAYS=365 PKCS12_FILE="server.p12" JKS_FILE="keystore.jks" # 1. 秘密鍵・証明書生成 openssl genrsa -out server.key ${KEY_SIZE} openssl req -new -key server.key -out server.csr \ -subj "/C=JP/ST=Tokyo/L=Shibuya/O=ExampleCorp/OU=IT/CN=example.local" openssl x509 -req -days ${VALID_DAYS} -in server.csr \ -signkey server.key -out server.crt # 2. PEM → PKCS12 openssl pkcs12 -export -in server.crt -inkey server.key \ -name ${KEY_ALIAS} -out ${PKCS12_FILE} -passout pass:${KEYSTORE_PASS} # 3. PKCS12 → JKS keytool -importkeystore -deststorepass ${KEYSTORE_PASS} \ -destkeypass ${KEYSTORE_PASS} -destkeystore ${JKS_FILE} \ -srckeystore ${PKCS12_FILE} -srcstoretype PKCS12 \ -srcstorepass ${KEYSTORE_PASS} -alias ${KEY_ALIAS} # 4. 確認 keytool -list -v -keystore ${JKS_FILE} -storepass ${KEYSTORE_PASS}
このスクリプトは、chmod +x create-jks.sh で実行権限を付与し、./create-jks.sh とすれば完了です。CI ツール(GitHub Actions、GitLab CI 等)に組み込む場合は、環境変数でパスワードを注入することでセキュリティを確保できます。
まとめ
本記事では、Java アプリで SSL/TLS を利用するための JKS キーストア作成手順 を、自己署名証明書の生成から PEM→PKCS12→JKS への変換までフルカバーしました。
- 手順1:
opensslで RSA 鍵と自己署名証明書を作成 - 手順2:PEM ファイルを PKCS12 に変換しエイリアスを付与
- 手順3:
keytoolで PKCS12 を JKS にインポート - ポイント:パスワードの統一、エイリアス管理、エラーハンドリング
この記事を読むことで、ローカル開発環境や CI パイプラインで安全に JKS キーストアを自動生成できるようになり、手動作業によるミスや時間ロスを大幅に削減できます。次回は、取得した正式証明書を JKS に組み込む実践例や、Spring Boot での SSL 設定方法を取り上げる予定です。
参考資料
- Java KeyStore (JKS) 公式ドキュメント
- OpenSSL コマンドラインリファレンス
- Spring Boot での SSL 設定ガイド
- 「実践 Java セキュリティ」 (技術評論社、2022 年)
