我正在尝试设置SSL套接字连接(并且正在客户端上执行以下操作)
1.我生成证书签名请求以获取已签名的客户端证书
1.现在我有了一个私钥(在CSR期间使用)、一个签名的客户端证书和根证书(带外获得)。
1.我将私钥和签名的客户端证书添加到证书链中,并将其添加到密钥管理器中,将根证书添加到信任管理器中,但是我得到了一个糟糕的证书错误。
我很确定我使用的证书是正确的。我应该把签名的客户证书也添加到信任管理器中吗?试过了,还是没有运气。
//I add the private key and the client cert to KeyStore ks
FileInputStream certificateStream = new FileInputStream(clientCertFile);
CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
java.security.cert.Certificate[] chain = {};
chain = certificateFactory.generateCertificates(certificateStream).toArray(chain);
certificateStream.close();
String privateKeyEntryPassword = "123";
ks.setEntry("abc", new KeyStore.PrivateKeyEntry(privateKey, chain),
new KeyStore.PasswordProtection(privateKeyEntryPassword.toCharArray()));
//Add the root certificate to keystore jks
FileInputStream is = new FileInputStream(new File(filename));
CertificateFactory cf = CertificateFactory.getInstance("X.509");
java.security.cert.X509Certificate cert = (X509Certificate) cf.generateCertificate(is);
System.out.println("Certificate Information: ");
System.out.println(cert.getSubjectDN().toString());
jks.setCertificateEntry(cert.getSubjectDN().toString(), cert);
//Initialize the keymanager and trustmanager and add them to the SSL context
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
kmf.init(ks, "123".toCharArray());
TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
tmf.init(jks);
是否需要在此处创建某种证书链?
我有一个p12也有这些组件,使用非常相似的代码,把私钥添加到密钥管理器,把根证书从p12添加到信任管理器,我可以让它工作,但是现在我需要在没有p12的情况下让它工作。
编辑:已请求堆栈跟踪。希望这已足够。(注意:我屏蔽了文件名)
Caused by: javax.net.ssl.SSLHandshakeException: Received fatal alert: bad_certificate
at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:174)
at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:136)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.recvAlert(SSLSocketImpl.java:1720)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:954)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1138)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1165)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1149)
at client.abc2.openSocketConnection(abc2.java:33)
at client.abc1.runClient(abc1.java:63)
at screens.app.abc.validateLogin(abc.java:197)
... 32 more
4条答案
按热度按时间inb24sb21#
您还需要将根证书添加到密钥存储库中。
iovurdzv2#
如果JKS中使用的证书之一已超过其到期日,也会出现此错误。
在我的特定测试中,我使用JRE8到IBM MQ over SSL,并且个人证书已经过了有效期,我只在
bad_certificate
是JRE版本或IBM MQ SSL握手的症状时才提到这一点。这并不一定能回答这个问题,因为作者说他们刚刚生成了一个证书,但是如果有人谷歌的错误(像我一样),你可能会在这里结束。
dphi5xsq3#
当我删除这两行代码时,我得到了这个错误。如果你知道你的密钥库有正确的证书,请确保你的代码正在查看正确的密钥库。
我还需要以下VM参数:
-Djavax.net.ssl.trustStore=/app/certs/keystore.jk
查看此处了解更多详情:https://stackoverflow.com/a/34311797/13084539fkzdhlc4#
如果服务器证书已签名且有效,则只需照常打开连接:
请注意,URL具有HTTPS模式以指示SSL的使用。
如果服务器的证书已签名,但您使用的IP地址/域名与证书中的IP地址/域名不同,则可以使用以下命令绕过主机名验证:
如果证书没有签名,则需要将其添加到JVM使用的密钥库(useful commands)。