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

标签 java ssl apache-httpclient-4.x tls1.2

我正在尝试使用相互 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

最佳答案

正如 @Gimby 所指出的,问题是我的 CA 证书在我的 keystore 中未被识别为 TrustCertEntry。

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

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

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

关于java - 如何配置 apache httpclient 4.5+ SSLContext 以使用带有自签名证书的双向 TLS 身份验证?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60284762/

相关文章:

java - 使用 Java 创建 excel

ssl - 如何在 IIS 6.0 上生成带有 SubjectAltNames 的证书请求?

node.js - 将 AWS EC2 上托管的网站的 http 请求重定向到 https

java.lang.NoSuchFieldError : INSTANCE with Spring Social on Azure 错误

java - 如何使用 HttpAsyncClient 进行多线程操作?

java - 在 Tomcat 5.5 上运行应用程序

java - 使用反射来使用特定的类构造函数并创建新对象

java - Apache HttpClient postman

java - 为什么 JSplitPane 会混合我的 GridBagLayout?

vb.net - 以编程方式修改自托管服务的 web.config(不是通过更改 applicationHost.config)