我是SSL/TLS的新手。我正在编写一个java客户端,它将对URL执行一个简单的get请求。但除了网址之外,我还必须发送提供给我的客户端证书(.p7b)。我已经将.p7b文件中存在的所有证书解压到单独的.cert文件中,并将这些.cert文件添加到java信任存储中。但是,在执行完所有步骤之后,当我到达该端点时,我会收到以下警告
*** ServerHelloDone
[read] MD5 and SHA1 hashes: len = 4
0000: 0E 00 00 00 ....
Warning: no suitable certificate found - continuing without client authentication
*** Certificate chain
<Empty>
***这是我用来配置rest模板的java代码
@Bean
public RestTemplate getTemplate(RestTemplateBuilder builder) throws Exception{
char[] password = "changeit".toCharArray();
SSLContext sslContext = SSLContextBuilder.create()
.loadTrustMaterial(keyStore("classpath:truststore/truststore.jks", password), new TrustSelfSignedStrategy())
.build();
HttpClient client = HttpClients.custom().setSSLContext(sslContext).build();
return builder
.requestFactory(new HttpComponentsClientHttpRequestFactory(client))
.build();
}
private KeyStore keyStore(String file, char[] password) throws Exception {
KeyStore keyStore = KeyStore.getInstance("JKS");
File key = ResourceUtils.getFile(file);
try (InputStream in = new FileInputStream(key)) {
keyStore.load(in, password);
}catch(Exception e) {
e.printStackTrace();
}
return keyStore;
}我不能弄清楚我错过了什么。请帮帮忙
发布于 2020-10-27 17:06:12
如果您所说的“发送客户端证书”实际上是指执行SSL/TLS客户端身份验证,尽管您省略了日志中直接显示它的部分,但您尝试连接的服务器明确请求了SSL/TLS客户端身份验证,这不仅仅包括发送证书。发送证书并不能证明身份,因为任何人都可以复制和发送证书。为了进行身份验证和证明身份,系统中的SSL/TLS实现(这里是Java的JSSE组件)必须发送证书,如果需要,还必须发送链式证书,并在握手中使用相应的privatekey对某些数据进行签名。有些人只注意到了第一部分,因此只谈论了第一部分,但没有第二部分就没有用了。
简而言之,仅仅发送证书的是无用的,这意味着仅仅拥有证书是无用的。您必须同时拥有证书(通常是链)和私有密钥,但显然没有,因为p7b不能包含私有密钥。
正常和推荐的过程是您从CA (或从CA获得证书的人)获得证书(可能但不一定是p7b ),因为您首先生成了证书签名请求(证书签名请求),在这种情况下,您已经拥有私钥--找到它并使用它。使用它的方法取决于它的形式,而这又取决于您是如何生成它的,这一点您没有说过,但您最终会希望得到一个可以提供给.loadKeyMaterial而不是Trust的KeyStore对象。(如果服务器在不是已建立的“公共”CA之一的CA(或锚点)下使用证书,则仅需要或应该使用.loadTrustMaterial。)
如果其他人生成了CSR并(然后)获得了证书,他们需要向您提供私钥,或者您需要从他们那里获得私钥,然后将其与上面的证书一起使用。
https://stackoverflow.com/questions/64149501
复制相似问题