我不知道我到底需要在哪里包括客户证书。现在,我的第一个问题是我不信任服务器。我尝试使用默认的Java文件(仙人掌),其中包含Thawte和Digicert,它们是我试图与之通信的服务器的根权限。我使用System.setProperty("javax.net.ssl.keyStore", "...")将仙人掌文件设置为keystore,它不起作用,我把它设置为信任库,它不起作用。我还有
无法找到被请求目标的有效证书路径
所以我用AlwaysTrustSSLConnectionFactory()暂时解决了这个问题。
现在的问题是服务器不信任我。我有一个客户端证书,我尝试将它添加到密钥存储库和信任存储库中,但是不管我做什么,在ServerHelloDone之后我得到了
警告:没有找到合适的证书-未经客户身份验证继续进行
在Java的SSL中,调试消息和秘密和密钥消息之后的握手失败。下面是我日志的结尾:
http-bio-8080-exec-3, WRITE: TLSv1.2 Handshake, length = 40
http-bio-8080-exec-3, READ: TLSv1.2 Alert, length = 2
http-bio-8080-exec-3, RECV TLSv1.2 ALERT: fatal, handshake_failure
%% Invalidated: [Session-7, TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384]
http-bio-8080-exec-3, called closeSocket()
http-bio-8080-exec-3, handling exception: javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
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.https.HttpsURLConnectionImpl.connect(Unknown Source)以下是我的当前代码:
System.setProperty("javax.net.ssl.keyStore", "C:/Users/Lovro/Desktop/certs/api/keystore.jks");
System.setProperty("javax.net.ssl.keyStorePassword", "pass");
URL url = new URL(urlRequest);
HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
conn.setSSLSocketFactory(new AlwaysTrustSSLContextFactory());
conn.connect();我收到了来自API开发人员的.p12格式的客户端证书,因此我将其转换为.crt,并使用Keytool将其添加到keystore中。有没有人知道这可能是什么问题,我的握手失败是因为我没有正确地包含客户端证书,或者如果我没有正确地将它添加到keystore中?据我所知,信任库需要包含受信任的根权限的公钥,密钥存储库应该有我的客户端证书。这是正确的吗?我怎样才能做到这一点?
欢迎任何建议,我对TLS/HTTPS并不熟悉,也不知道我在做什么。
发布于 2018-09-25 08:30:52
我从API开发人员那里收到了.p12格式的客户端证书,因此我将其转换为.crt,并使用Keytool将其添加到keystore中。
这就是你出错的地方。将其转换为.crt将提取公共证书。您需要做的是将.p12文件转换为。网上有很多例子。有关如何使用,请参见这就是答案。
要确认它是否有效,请运行keytool -list -keystore <yourkeystore>.jks并检查其中是否有PrivateKeyEntry。
在检查内容时,将-v标志添加到keytool -list命令中,并检查Issuer字段是否为CN=test, O=test,因为我们可以从日志文件中看到您的服务器需要由该权威机构颁发客户端证书。
还要检查您的JDK是否配置了无限强权限政策档案,因为您被要求使用的密码需要它。
发布于 2018-09-25 08:22:14
从日志中可以看出,TLS密码TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384对于TLS客户端是无效的。您可能需要检查哪个密码列表客户端支持。如果密码TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384未包含在密码列表中,则可能需要添加对它的支持。
http-bio-8080-exec-3,阅读: TLSv1.2警报,长度=2 http-bio-8080-exec-3,RECV TLSv1.2警报:致命,handshake_failure %无效: Session-7,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
https://stackoverflow.com/questions/52493278
复制相似问题