不信任[myserver.mydomain.com]

时间:2018-09-21 16:16:15

标签: java ssl openssl keytool truststore

尝试使用自定义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 / w质询密码(openssl req -new -key mykey.key -out mykey.csr
  • 生成自签名证书公钥对证书(openssl req -x509 -days 365 -key mykey.key -in mykey.csr -out mykey.cer
  • 根据私钥(openssl pkcs12 -export -out mykey.p12 -inkey mykey.key -in mykey.cer)生成PKCS12文件
  • 将新的PKCS12文件添加到新的密钥库(keytool -importkeystore -srckeystore mykey.p12 -destkeystore mykeystore.jks -srcstoretype PKCS12
  • 将服务器的公共证书从pem转换为derkeytool -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 Intermediate证书签名的。因此,我还将Digicert的中间证书和根证书都添加到了信任库(而不是密钥库)中,但这是行不通的。

但是,如果我将中间证书和根证书放在了从客户端到服务器的openssl连接中,则它成功连接了,这使我相信这与java truststore有关。


编辑:我使用以下命令在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>

1 个答案:

答案 0 :(得分:0)

从您的问题中还不清楚您正在使用哪个信任库。您是否使用类似的方法将自签名证书加载到默认信任存储中?

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 opts:

-Djavax.net.ssl.keyStore=<path to your keystore>.jks -Djavax.net.ssl.keyStorePassword=<your keystore password>