java - [myserver.mydomain.com] 不受信任的 Java 信任库根证书
问题描述
我在尝试使用自定义 java 信任库连接到服务器时遇到了一些困难,当我尝试连接时出现以下错误。我几乎没有使用 java 通过 SSL 进行连接的经验,所以我担心有一些我不知道会导致问题:
javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException: root certificate not trusted of [myserver.mydomain.com]
at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1884)
at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:276)
at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:270)
at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1341)
at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:153)
at sun.security.ssl.Handshaker.processLoop(Handshaker.java:868)
at sun.security.ssl.Handshaker.process_record(Handshaker.java:804)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1016)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1312)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1339)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1323)
at org.jiv
该连接需要我以以下方式创建的密钥库和信任库:
密钥库:
- 在客户端生成私钥 (
openssl genrsa -out mykey.key 4096
) - 生成了一个自签名的 CSR /wa 质询密码 (
openssl req -new -key mykey.key -out mykey.csr
) - 生成自签名证书公钥对证书 (
openssl req -x509 -days 365 -key mykey.key -in mykey.csr -out mykey.cer
) - 从私钥生成 PKCS12 文件 (
openssl pkcs12 -export -out mykey.p12 -inkey mykey.key -in mykey.cer
) - 将新的 PKCS12 文件添加到新的密钥库 (
keytool -importkeystore -srckeystore mykey.p12 -destkeystore mykeystore.jks -srcstoretype PKCS12
) - 将服务器的公共证书从
pem
转换为der
(keytool -import -alias mnt1 -keystore mykeystore.jks -file puiblicserver.der
)后添加到密钥库
信任库:
- 将相同的公钥从服务器添加到新的信任库 (
keytool -import -alias root -keystore truststore.jks -file puiblicserver.der
)
从那里我将 mykey.cer 上传到服务器的受信任证书存储。我注意到的一件事是,当我使用我的 jar 文件 ( java -Djavax.net.debug=ssl,handshake -jar myjar.jar myserver.mydomain.com User truststore.jks <PW> mykeystore.jks <PW>
) 检查连接时,服务器实际上是由 Digicert 中间证书签名的。因此,我还将 Digicert 的中间证书和根证书都添加到了信任库(不是密钥库)中,但这不起作用。
但是,如果我 cat 中间证书和根证书并在从客户端到它成功连接的服务器的 openssl 连接中使用它们,这让我相信这与 java 信任库有关。
编辑:我在java中调用连接,如下所示:
TLSConfiguration config = new TLSConfiguration();
config.setHosts(hostnames);
config.setUserName(username);
config.setGroup(Group.EPS.value());
config.setKeystorePath(keystoreFilename);
config.setKeystorePassphrase(keystorePassword);
config.setTruststorePath(truststoreFilename);
config.setTruststorePassphrase(truststorePassword);
例子:java -Djavax.net.debug=ssl,handshake -jar myjar.jar myserver.mydomain.com User truststore.jks <PW> mykeystore.jks <PW>
解决方案
您的问题并不清楚您正在使用哪个信任存储。您是否使用类似的方式将自签名证书加载到默认信任库中?
keytool -import -trustcacerts -keystore cacerts -storepass changeit -noprompt -alias yourAliasName -file path\to\certificate.cer
如果没有,您需要告诉 Java 使用哪个信任库。如果您不这样做,它将使用默认值(其中没有您的自签名证书)。你需要这样做:
-Djavax.net.ssl.trustStore=<path to your trusstore>.jks -Djavax.net.ssl.trustStorePassword=<your password>
注意:如果您通过 -D 参数设置信任库,您的代码将仅信任该信任库中的 CA。
要指定要使用的密钥库,您可以添加这些 java 选项:
-Djavax.net.ssl.keyStore=<path to your keystore>.jks -Djavax.net.ssl.keyStorePassword=<your keystore password>
推荐阅读
- c# - 释放数字键时未触发 KeyUp 事件 C# devexpress
- c - 如何将此代码从 C 转换为 Mips?
- python - Ctypes 获取窗口位置
- c++ - 如何将二进制数据写入字符串或字符串流?
- amazon-web-services - S3 put 命令方法的安全性如何?
- flutter - Flutter CircularProgressIndicator 描边类型
- javascript - 范围格式数字输入的自定义输入字段问题 [低-高]
- c# - 线条形状看起来很奇怪
- google-developers-console - 谷歌开发者账号激活
- heroku - 使用 heroku-buildpack-rust 构建 Rocket 应用程序时出现链接错误