Java 使用自定义CA证书、客户端证书和私钥,将HttpClient 4.5.x用于SSL请求

Java 使用自定义CA证书、客户端证书和私钥,将HttpClient 4.5.x用于SSL请求,java,ssl,puppet,apache-httpclient-4.x,apache-commons-httpclient,Java,Ssl,Puppet,Apache Httpclient 4.x,Apache Commons Httpclient,因此,我尝试使用HttpClient 4.5.3向一个使用自己证书签名的PuppetDB端点发出SSL请求。以下来自works fine的cUrl查询: curl -X GET https://hostname:8081/pdb/query/v4/resources \ --tlsv1 \ --cacert /etc/puppetlabs/puppet/ssl/certs/ca.pem \ --cert /etc/puppetlabs/puppet/ssl/certs/hostnam

因此,我尝试使用HttpClient 4.5.3向一个使用自己证书签名的PuppetDB端点发出SSL请求。以下来自works fine的cUrl查询:

curl -X GET https://hostname:8081/pdb/query/v4/resources \
  --tlsv1 \
  --cacert /etc/puppetlabs/puppet/ssl/certs/ca.pem \
  --cert /etc/puppetlabs/puppet/ssl/certs/hostname.pem \
  --key /etc/puppetlabs/puppet/ssl/private_keys/hostname.pem \
  --data-urlencode query@query.txt
我试过文档,但不起作用。我在网上找到的大多数示例是HttpClient<4.3,所有这些方法都不推荐使用。我尝试允许具有以下内容的所有证书:

SSLContextBuilder sshbuilder = new SSLContextBuilder();
sshbuilder.loadTrustMaterial(null, new TrustSelfSignedStrategy());
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sshbuilder.build());

try(CloseableHttpClient httpclient = HttpClients.custom()
        .setSSLSocketFactory(sslsf)
        .build()) {
    HttpGet get = new HttpGet(uri);
    httpclient.execute(get, (ResponseHandler<Void>) response -> {
        StatusLine line = response.getStatusLine();
        int code = line.getStatusCode();
        logger.println("Response code: " + code);

        return null;
    });
}

任何帮助都会很好。谢谢

您是否尝试在客户端显式使用TLSV1,因为JDK 8默认使用TLSV1.2?我假设您已将puppet key、certificate和CA certificate添加到一些Java keystore.jks中,您可以临时替换位于$Java_HOME/jre/lib/security/cacerts下的JVM keystore.jks,并尝试使用默认值构建SSLContext,检查这是否有效。@Timothy我尝试了TLSv1和TLS1.2,但都没有成功。@AntonKrosnev我希望通过编程方式将文件作为参数传入。这不可能吗?@KeithMiller我认为首先将其转换为.jks会更容易,否则您应该编写一些代码来加载证书和密钥,如:您是否尝试在客户端显式使用TLSV1,因为JDK 8默认使用TLSV1.2?我假设您已将puppet key、certificate和CA certificate添加到一些Java keystore.jks中,您可以临时替换位于$JAVA_HOME/jre/lib/security/cacerts下的JVM keystore.jks,并尝试使用默认值构建SSLContext,以检查这是否有效。@Timothy我尝试了TLSv1和TLS1.2,没有成功。@AntonKrosnev我希望以编程方式将文件作为参数传入。这不可能吗?@KeithMiller我认为首先将其转换为.jks会更容易,否则您应该编写一些代码来加载证书和密钥,如:
Executor #0 for master : executing test #44, WRITE: TLSv1 Handshake, length = 48
Executor #0 for master : executing test #44, received EOFException: error
Executor #0 for master : executing test #44, handling exception: javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake
%% Invalidated:  [Session-1, TLS_RSA_WITH_AES_128_CBC_SHA]
Executor #0 for master : executing test #44, SEND TLSv1 ALERT:  fatal, description = handshake_failure
Executor #0 for master : executing test #44, WRITE: TLSv1 Alert, length = 32
Executor #0 for master : executing test #44, called closeSocket()
javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake