3 回答
TA贡献1812条经验 获得超5个赞
你应该尝试像这样构建客户端
// Creating SSLContextBuilder object
SSLContextBuilder SSLBuilder = SSLContexts.custom();
// Loading the Keystore file
File file = new File("mykeystore.jks");
SSLBuilder = SSLBuilder.loadTrustMaterial(file, "changeit".toCharArray());
// Building the SSLContext usiong the build() method
SSLContext sslcontext = SSLBuilder.build();
// Creating SSLConnectionSocketFactory object
SSLConnectionSocketFactory sslConSocFactory = new SSLConnectionSocketFactory(sslcontext,
new NoopHostnameVerifier());
// Creating HttpClientBuilder
HttpClientBuilder clientbuilder = HttpClients.custom();
// Setting the SSLConnectionSocketFactory
clientbuilder = clientbuilder.setSSLSocketFactory(sslConSocFactory);
// Building the CloseableHttpClient
CloseableHttpClient httpclient = clientbuilder.build();
TA贡献2037条经验 获得超6个赞
您的客户端没有按照服务器(肯定)请求且显然需要的方式发送客户端证书。
请注意,您的信任库没有任何问题,更改您的信任库或信任管理器完全无关且无用。那些认为所有 SSL/TLS 问题都缺乏验证(信任)服务器证书的人就像那些认为如果发动机已从汽车上拆下,只要放一些汽油(或汽油/香精),它仍然会运行良好的人/etc 取决于国家)在水箱中。
从你的调试日志:
*** CertificateRequest
Cert Types: RSA, DSS, ECDSA
Supported Signature Algorithms: SHA256withRSA, SHA256withDSA, SHA256withECDSA, SHA384withRSA, Unknown (hash:0x5, signature:0x2), SHA384withECDSA, SHA512withRSA, Unknown (hash:0x6, signature:0x2), SHA512withECDSA, SHA1withRSA, SHA1withDSA, SHA1withECDSA
Cert Authorities:
<CN=m3_external_ca_test>
服务器请求客户端证书,又名客户端身份验证(认证),又名双向身份验证或相互身份验证。
Warning: no suitable certificate found - continuing without client authentication
*** Certificate chain
<Empty>
***
...
*** ECDHClientKeyExchange
[Raw read]: length = 2
0000: 02 28 .(
main, READ: TLSv1.2 Alert, length = 2
main, RECV TLSv1.2 ALERT: fatal, handshake_failure
您没有提供一份(以及证明拥有的相关签名)。服务器中止握手,通常可能有多种原因,但此时唯一可能的原因是您没有提供所请求的证书(和签名)。
返回顶部附近:
keyStore is : /Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/jre/lib/security/jssecacerts
keyStore type is : jks
keyStore provider is :
init keystore
init keymanager of type SunX509
请注意,本节没有说类似的内容,就像可用的客户端证书一样:
found key for : <alias>
chain [0] = [ <usually dozens of lines of data> ]
<usually chain[1], maybe chain[2] and more depending>
有两种截然不同的证书:一种是识别您(或您的设备等)并且您希望其他人信任的证书,您必须拥有 privatekey ;另一种是识别您信任的其他人的证书,您应该拥有该私钥永远没有私钥。对于客户端身份验证,您需要第一种,但您没有。(补充说明:一般来说,对于您自己的证书,您还需要一个或有时多个“链”或“中间”证书,但在这种情况下,调试日志清楚地表明您正在使用不使用的虚拟/测试 CA链证书。)
要么是您或其他人准备jssecacerts错误,要么是使用错误的文件,因为它旨在包含您信任的其他人的证书,即 CA,Java 称之为信任库(尽管它仍然是密钥库格式),并且不是您自己的证书,这是真正的密钥库。第三个证书被列为受信任,带有EMAILADDRESS=rchhabra@xpwallet.com,看起来它可能是客户端证书,但由于您没有私钥,所以不能这样使用。修复该文件,或者如果您在不同的文件中拥有带有密钥的客户端证书(这将是一个很好且常用的方法),请改用该不同的文件。
TA贡献1856条经验 获得超5个赞
我们通常使用 TrustStore 来信任第 3 方服务器通信。在通过 HTTPS 协议进行客户端和服务器通信时,后者始终查找其密钥库并将其呈现the public key and certificate
给前者。之后,客户端查找associated certificate in the truststore
. 如果调用服务器共享的证书或证书颁发机构不存在于客户端信任存储中(默认情况下,Java 始终将信任存储捆绑为 cacerts 并将其保留在 $JAVA_HOME/jre/lib/security 路径中),则会SSLHandshakeException
发生这种情况。要解决该问题,您必须添加信任存储。
可以使用以下命令列出默认受信任的证书颁发机构
keytool -list -keystore cacerts
您可以使用以下命令添加信任存储:
keytool -import -trustcacerts -alias certAlias -file certFile -keystore trustStoreFile
默认情况下,trustStoreFile 位置为 $JAVA_HOME/jre/lib/security/cacerts。
添加回答
举报