如何配置apache httpclient 4.5+ SSLContext以使用具有自签名证书的双向TLS身份验证?

问题描述 投票:0回答:1

我正在尝试使用相互TLS身份验证从httpclient 4.5配置CloseableHttpClient。服务器证书是自签名的。这是我使用的代码(各种StackOverflow帖子都标出了):

KeyStore trustStore = KeyStore.getInstance("pkcs12");
try (InputStream fis = new FileInputStream(ssl_cert_file)) {
    trustStore.load(fis, password.toCharArray());
}
SSLContext sslContext = SSLContexts.custom()
        .loadKeyMaterial(trustStore, password.toCharArray(), (map, socket) -> "client")
        .loadTrustMaterial(trustStore, new TrustSelfSignedStrategy())
        .build();
SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(sslContext,  new DefaultHostnameVerifier());
Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create()
        .register("https", socketFactory).build();
connectionManager = new PoolingHttpClientConnectionManager(registry);

我有

sun.security.provider.certpath.SunCertPathBuilderException: 
unable to find valid certification path to requested target

我认为未使用我提供的CA证书。知道什么地方可能出问题了吗?


CA的证书,客户端的证书和客户端的私钥位于pkcs12文件中用

生成
openssl pkcs12 -export -in client-cert.pem -inkey private/client-key.pem -certfile cacert.pem -name "client" -out client-cert.p12

我尝试openssl s_client检查证书是否返回了预期的输出(确实如此)。我怀疑问题出在我的代码而不是client-cert.p12文件。

openssl s_client -connect host:port -tls1 -cert client-cert.pem -key private/client-key.pem -CAfile cacert.pem
java ssl apache-httpclient-4.x tls1.2
1个回答
0
投票

如@Gimby所指出的,问题是我的CA中的证书未在我的密钥库中识别为TrustCertEntry。

我的解决方法是仅为CA的证书生成jks文件:

keytool -import -alias client -file cacert.pem -storetype JKS -keystore cacert.jks

从其构建一个KeyStore对象,并将其用于SSLContext.loadTrustMaterial

© www.soinside.com 2019 - 2024. All rights reserved.