我已经获得3个文件:MY.cer,MY.key,B.pem(root,中间证书)。使用openssl我得到了一个成功的连接:
openssl s_client -connect abc.com:10101 -cert MY.cer -key MY.key, -CAfile B.pem
使用openssl,我们捆绑了MY.cer和MY.key(pkcs12),并使用keytool将该对导入keystore.jks,然后将B.pem导入truststore.jks。我们的Java SSLConnector对象(我们在这里随处可用)barfs:
main, READ: TLSv1 Alert, length = 2
main, RECV TLSv1 ALERT: fatal, bad_certificate
%% Invalidated: [Session-1, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA]
main, called closeSocket()
main, handling exception: javax.net.ssl.SSLHandshakeException: Received fatal alert: bad_certificate
main, called close()
main, called closeInternal(true)
javax.net.ssl.SSLHandshakeException: Received fatal alert: bad_certificate
at sun.security.ssl.Alerts.getSSLException(Unknown Source)
at sun.security.ssl.Alerts.getSSLException(Unknown Source)
at sun.security.ssl.SSLSocketImpl.recvAlert(Unknown Source)
at sun.security.ssl.SSLSocketImpl.readRecord(Unknown Source)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(Unknown Source)
at sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source)
at sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source)
at sun.net.www.protocol.https.HttpsClient.afterConnect(Unknown Source)
at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(Unknown Source)
at sun.net.www.protocol.http.HttpURLConnection.getOutputStream(Unknown Source)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getOutputStream(Unknown Source)
at com.dam.system.SSLConnector.sendPost(SSLConnector.java:132)
SSLConnector使用HttpsUrlConnection,并且对于这个新客户的服务器,我们第一次看到此错误。
我们已经检查了openssl调试,javax.ssl调试,广泛搜索,尝试了portecle和InstallCert.java(它们都显示了bad_certificate),没有解析。
服务器有什么理由认为我们的证书在JSSE中不好,但是从openssl开始也不错?
答案 0 :(得分:1)
问题完全在于密钥库的创建方式。
列表而不是链:客户端及其根和中间CA证书(来自B.pem文件)分别导入到keystore.jks中(显示为列表)而不是相互附加到一个链。我们使用kse v5.1.1删除CA证书,然后编辑链并将其追加。
缺少服务器证书。 truststore.jks具有CA证书而不是服务器证书。使用openssl获取服务器的证书和keytool以创建新的truststore.jks。
现在一切都运行完美无需更改任何Java代码。