サーバ(tomcat)

サーバ構成

1. 秘密鍵を作成

"c:\Program Files\OpenSSL-Win64\bin\openssl.exe" genrsa -out d:\ssl\server.key 2048

2. CSR(証明書署名要求)を作成

"c:\Program Files\OpenSSL-Win64\bin\openssl.exe" req -new -key d:\ssl\server.key -out d:\ssl\server.csr -subj "/C=JP/ST=Tokyo/L=Tokyo/O=MyOrg/OU=Dev/CN=localhost"

3. 自己署名証明書を作成(有効期限365日)

"c:\Program Files\OpenSSL-Win64\bin\openssl.exe" x509 -req -days 365 -in d:\ssl\server.csr -signkey d:\ssl\server.key -out d:\ssl\server.crt

4. PKCS12形式に変換(Tomcat用)

"c:\Program Files\OpenSSL-Win64\bin\openssl.exe" pkcs12 -export -in d:\ssl\server.crt -inkey d:\ssl\server.key -out d:\ssl\server.p12 -name tomcat -passout pass:changeit

ファイルの確認

D:\ssl のディレクトリ 2025/05/11 22:26 <DIR> . 2025/05/11 22:26 1,270 server.crt 2025/05/11 22:25 1,010 server.csr 2025/05/11 22:25 1,732 server.key 2025/05/11 22:26 2,704 server.p12 4 個のファイル 6,716 バイト 1 個のディレクトリ 222,650,269,696 バイトの空き領域

tomcat server.xml

<Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol" maxThreads="200" SSLEnabled="true" scheme="https" secure="true" keystoreFile="d:\ssl\server.p12" keystorePass="changeit" keystoreType="PKCS12" keyAlias="tomcat" sslProtocol="TLS" />

tomcat 再起動

停止

d:\dev\container\tomcat9\bin\shutdown.bat

起動

D:\dev\container\tomcat9\bin>startup.bat Using CATALINA_BASE: "D:\dev\container\tomcat9" Using CATALINA_HOME: "D:\dev\container\tomcat9" Using CATALINA_TMPDIR: "D:\dev\container\tomcat9\temp" Using JRE_HOME: "D:\dev\runtime\java\jdk\jdk-17.0.14" Using CLASSPATH: "D:\dev\container\tomcat9\bin\bootstrap.jar;D:\dev\container\tomcat9\bin\tomcat-juli.jar" Using CATALINA_OPTS: "-Xlog:gc*:file=d:\dev\runtime\logs\sono0\gc.log:time,uptime,level,tags:filecount=60"

クライアント

自己署名証明書を信頼ストアに追加

keytool -import -trustcacerts -alias simpletomcatssl -file d:\ssl\server.crt -keystore d:\dev\runtime\java\truststore.jks -storepass changeit

実行例

D:\dev\runtime\java>keytool -import -trustcacerts -alias simpletomcatssl -file d:\ssl\server.crt -keystore d:\dev\runtime\java\truststore.jks -storepass changeit 所有者: CN=localhost, OU=Dev, O=MyOrg, L=Tokyo, ST=Tokyo, C=JP 発行者: CN=localhost, OU=Dev, O=MyOrg, L=Tokyo, ST=Tokyo, C=JP シリアル番号: 5caf266094f330d5f50e81b728027d1904b5fa6c 有効期間の開始日: Sun May 11 22:26:04 JST 2025終了日: Mon May 11 22:26:04 JST 2026 証明書のフィンガプリント: SHA1: AE:95:F5:9B:AD:53:7A:F4:51:65:DD:B9:7B:7E:09:C5:AF:38:AA:F0 SHA256: 43:31:C3:CC:47:43:17:F0:1D:89:19:28:52:4B:66:87:2D:14:F4:A2:5E:F3:37:AE:61:9D:6F:CE:C5:74:47:AE 署名アルゴリズム名: SHA256withRSA サブジェクト公開キー・アルゴリズム: 2048ビットRSAキー バージョン: 3 拡張: #1: ObjectId: 2.5.29.14 Criticality=false SubjectKeyIdentifier [ KeyIdentifier [ 0000: 49 8E 1B EE 69 74 D5 63 87 79 96 D6 3A 33 DE 0B I...it.c.y..:3.. 0010: 9F C9 9E 57 ...W ] ] この証明書を信頼しますか。 [いいえ]: y 証明書がキーストアに追加されました

キーストアの確認

keytool --list -keystore d:\dev\runtime\java\truststore.jks

D:\dev\runtime\java>keytool --list -keystore d:\dev\runtime\java\truststore.jks キーストアのパスワードを入力してください: キーストアのタイプ: PKCS12 キーストア・プロバイダ: SUN キーストアには4エントリが含まれます myserver,2025/05/11, trustedCertEntry, 証明書のフィンガプリント(SHA-256): 30:A8:85:62:18:BD:9B:1D:B8:73:BC:1F:08:4B:4E:86:A6:8D:8B:1A:29:1D:B2:D2:2C:ED:3D:6C:C7:2C:61:0E simpletomcatssl,2025/05/11, trustedCertEntry, 証明書のフィンガプリント(SHA-256): 43:31:C3:CC:47:43:17:F0:1D:89:19:28:52:4B:66:87:2D:14:F4:A2:5E:F3:37:AE:61:9D:6F:CE:C5:74:47:AE

Java Tomcat接続サンプル

SimpleSSLClient.java

import javax.net.ssl.HttpsURLConnection; import java.io.*; import java.net.URL; public class HttpsTest { public static void main(String[] args) throws Exception { System.setProperty("javax.net.ssl.trustStore", "D:\\dev\\runtime\\java\\truststore.jks"); System.setProperty("javax.net.ssl.trustStorePassword", "changeit"); URL url = new URL("https://localhost:8443/"); HttpsURLConnection conn = (HttpsURLConnection) url.openConnection(); conn.setRequestMethod("GET"); BufferedReader reader = new BufferedReader( new InputStreamReader(conn.getInputStream())); String line; while ((line = reader.readLine()) != null) { System.out.println(line); } reader.close(); } }

コンパイル

javac SimpleSSLClient.java

実行

java -Djavax.net.ssl.trustStore=d:\dev\runtime\java\truststore.jks -Djavax.net.ssl.trustStorePassword=changeit SimpleSSLClient

証明書エラーの時

D:\dev\runtime\java>java -Djavax.net.ssl.trustStore=d:\dev\runtime\java\truststore.jks -Djavax.net.ssl.trustStorePassword=changeit SimpleSSLClient Exception in thread "main" javax.net.ssl.SSLHandshakeException: PKIX path validation failed: java.security.cert.CertPathValidatorException: signature check failed at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:131) at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:378) at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:321) at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:316) at java.base/sun.security.ssl.CertificateMessage$T13CertificateConsumer.checkServerCerts(CertificateMessage.java:1351) at java.base/sun.security.ssl.CertificateMessage$T13CertificateConsumer.onConsumeCertificate(CertificateMessage.java:1226) at java.base/sun.security.ssl.CertificateMessage$T13CertificateConsumer.consume(CertificateMessage.java:1169) at java.base/sun.security.ssl.SSLHandshake.consume(SSLHandshake.java:396) at java.base/sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:480) at java.base/sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:458) at java.base/sun.security.ssl.TransportContext.dispatch(TransportContext.java:201) at java.base/sun.security.ssl.SSLTransport.decode(SSLTransport.java:172) at java.base/sun.security.ssl.SSLSocketImpl.decode(SSLSocketImpl.java:1506) at java.base/sun.security.ssl.SSLSocketImpl.readHandshakeRecord(SSLSocketImpl.java:1421) at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:455) at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:426) at java.base/sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:589) at java.base/sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:187) at java.base/sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1687) at java.base/sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1611) at java.base/sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:224) at SimpleSSLClient.main(SimpleSSLClient.java:13) Caused by: sun.security.validator.ValidatorException: PKIX path validation failed: java.security.cert.CertPathValidatorException: signature check failed at java.base/sun.security.validator.PKIXValidator.doValidate(PKIXValidator.java:369) at java.base/sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:275) at java.base/sun.security.validator.Validator.validate(Validator.java:264) at java.base/sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:231) at java.base/sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:132) at java.base/sun.security.ssl.CertificateMessage$T13CertificateConsumer.checkServerCerts(CertificateMessage.java:1335) ... 17 more Caused by: java.security.cert.CertPathValidatorException: signature check failed at java.base/sun.security.provider.certpath.PKIXMasterCertPathValidator.validate(PKIXMasterCertPathValidator.java:135) at java.base/sun.security.provider.certpath.PKIXCertPathValidator.validate(PKIXCertPathValidator.java:224) at java.base/sun.security.provider.certpath.PKIXCertPathValidator.validate(PKIXCertPathValidator.java:144) at java.base/sun.security.provider.certpath.PKIXCertPathValidator.engineValidate(PKIXCertPathValidator.java:83) at java.base/java.security.cert.CertPathValidator.validate(CertPathValidator.java:309) at java.base/sun.security.validator.PKIXValidator.doValidate(PKIXValidator.java:364) ... 22 more Caused by: java.security.SignatureException: Signature does not match. at java.base/sun.security.x509.X509CertImpl.verify(X509CertImpl.java:458) at java.base/sun.security.provider.certpath.BasicChecker.verifySignature(BasicChecker.java:166) at java.base/sun.security.provider.certpath.BasicChecker.check(BasicChecker.java:147) at java.base/sun.security.provider.certpath.PKIXMasterCertPathValidator.validate(PKIXMasterCertPathValidator.java:125) ... 27 more