当前位置: 首页 > 知识库问答 >
问题:

客户端证书握手失败的TLS

端木志诚
2023-03-14

我不知道我到底需要在哪里包含客户机证书。现在,我的第一个问题是我不信任服务器。我尝试使用默认的Java密钥库文件(cacerts),其中包含Thawte和Digicert,这些是我试图与之通信的服务器的根权限。我使用系统将该cacerts文件设置为密钥库。setProperty(“javax.net.ssl.keyStore”、“…”) ,它不工作,我将它设置为信任库,它不工作。我还有

无法找到到请求目标的有效认证路径

因此,我使用AlwaysTrustSSLConnectionFactory()暂时解决了这个问题。

现在的问题是服务器不信任我。我有一个客户端证书,我试图将它添加到keystore和信任库,但是不管我做什么,在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,并将其添加到keystore中。有人知道可能是什么问题吗?我的握手失败是因为我没有正确地包含客户端证书,还是因为我没有正确地将其添加到keystore?据我所知,信任库需要包含受信任根机构的公钥,密钥库应该有我的客户端证书。这样做正确吗?我如何实现这一点?

欢迎任何建议,我是TLS/HTTPS的新手,不知道我在做什么。


共有2个答案

冷涵忍
2023-03-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警报:致命,握手失败
%%无效:[会话7,TLS\u ECDHE\u RSA\u与\u AES\u 256\u GCM\u SHA384]

束俊材
2023-03-14

我从API开发人员处收到了格式为的客户端证书。p12,所以我把它转换成了。crt并使用Keytool将其添加到密钥库

这就是你错的地方。将其转换为。crt提取公共证书。您需要做的是转换。p12文件到java密钥库。网上有很多例子。看看这个答案。

要确认它工作正常,请运行keytool-list-keystore

检查时,将-v标志添加到keytool-list命令中,并检查颁发者字段是否为CN=test,O=test,因为我们可以从日志文件中看到,您的服务器需要由该机构颁发客户端证书。

还要检查您的JDK是否配置了无限强度权限策略文件,因为要求您使用的密码需要它。

 类似资料:
  • 我有一个客户端-服务器应用程序(Android客户端、Apache Http服务器),通过相互身份验证(TLS 1.2)进行通信。问题是:有时连接(登录)会因SSL错误而失败。 这是有效的: 注册客户端证书 登录 这是行不通的: 注册客户证书 注意:在步骤4之后杀死应用程序,然后启动它并执行步骤5工作。 我能想到的可能解释是: 正在重用一些旧资源(如旧客户端证书)。看起来所有相关的东西(OkHtt

  • 我有一个使用OpenSSL的C客户机,在服务器上的SSL_do_handshake()调用期间,使用服务器端验证失败的证书时,该客户机的测试失败。当应用程序使用TLS 1.2时,服务器上的SSL_do_handshake()故障将在客户端调用SSL_do_handshake()作为故障返回值时报告给客户端。 在将我的应用程序升级到OpenSSL 1.1.1和TLS 1.3时,我注意到验证错误仍在服

  • 我试图建立一个双向TSL连接到一个Web服务使用Java,我得到了一个pfx证书与一个私钥和3个证书的证书链。下面是使用Spring框架的java代码: 到目前为止,我得到了一个客户端你好和一个发送证书的服务器你好,我得到了一个找到的可信证书。然后有一个证书请求,它找不到任何证书 我已经将证书单独添加到lib/Security/cacerts中。似乎第一次证书交换发生在cacerts密钥存储库,因

  • 问题内容: 尝试获取网页: 获取https://www.fl.ru/:远程错误:握手失败。 如果我尝试获取另一个HTTPS页面-一切正常。 问题答案: 该服务器仅支持一些弱密码: 如果确实必须连接到该服务器,则Go会支持列表中的最后一个密码,但默认情况下不支持。使用新的tls.Config创建一个客户端,并指定所需的密码:

  • 尝试获取网页: 收到https://www.fl.ru/:远程错误:握手失败。 如果我尝试获取另一个HTTPS页面,一切都可以。

  • 问题内容: 我正在连接到以前成功使用过的Web服务,但是现在他们已经更改了主机名并向我发送了两个.pem文件。一个是CA,另一个是我的新客户证书。 (我将Java 1.5,Spring + Spring Web Services与Apache httpclient一起使用,但是我怀疑我的问题是证书,密钥和SSL本身。) 我已经导入了.pem文件以及从Firefox导出到cacerts中的主机的.c