Java 11 Apache HTTPClient SSL证书身份验证无效

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

我在代码下使用修改版本进行SSL客户端证书身份验证。它在JDK 8中工作,最近我改为JDK 11,现在使用相同的代码验证失败了。如果我切换到JDK 8它的工作原理。 JDK 11中的任何更改都要处理SSL客户端证书身份验证?任何使这段代码都能运行JDK的技巧都会有所帮助。

package org.example.test;

import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.HttpClientConnectionManager;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLContexts;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.conn.BasicHttpClientConnectionManager;
import org.apache.http.util.EntityUtils;
import org.junit.Test;

import javax.net.ssl.SSLContext;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.*;
import java.security.cert.CertificateException;

/**
 * Demonstrate connecting to a server secured with client-side SSL certificates.
 */
public class ConnectIT {

    /**
     * Path to your client-side SSL certificate in the PKCS12 format, as generated by OpenSSL.
     */
    final String KEY_STORE_PATH = "/path/to/pkcs12file.p12";

    /**
     * PKCS12 file passphrase.
     */
    final String KEY_STORE_PASSWORD = "correct horse battery staple";

    /**
     * URL to connect to. That is, a server for which the above certificate is required.
     */
    final String URL = "https://secure.example.org";

    @Test
    public void sslConnect() throws KeyStoreException, IOException, CertificateException,
            NoSuchAlgorithmException, KeyManagementException, UnrecoverableKeyException {

        // Load the key store, containing the client-side certificate.
        KeyStore keyStore = KeyStore.getInstance("pkcs12");
        InputStream keyStoreInput = new FileInputStream(KEY_STORE_PATH);
        keyStore.load(keyStoreInput, KEY_STORE_PASSWORD.toCharArray());
        System.out.println("Key store has " + keyStore.size() + " keys");

        // Create an SSL context with our private key store.
        // We are only loading the key-material here, but if your server uses a self-signed certificate,
        // you will need to load the trust-material (a JKS key-store containing the server's public SSL
        // certificate) as well.
        SSLContext sslContext = SSLContexts.custom()
                .loadKeyMaterial(keyStore, KEY_STORE_PASSWORD.toCharArray())
                .useTLS()
                .build();

        // Prepare the HTTPClient.
        HttpClientBuilder builder = HttpClientBuilder.create();
        SSLConnectionSocketFactory sslConnectionFactory = new SSLConnectionSocketFactory(
                sslContext, SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
        builder.setSSLSocketFactory(sslConnectionFactory);
        Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create()
                .register("https", sslConnectionFactory)
                .register("http", new PlainConnectionSocketFactory())
                .build();
        HttpClientConnectionManager ccm = new BasicHttpClientConnectionManager(registry);
        builder.setConnectionManager(ccm);

        // Perform a sample HTTP request.
        try (CloseableHttpClient httpClient = builder.build()) {
            HttpGet httpget = new HttpGet(URL);
            try (CloseableHttpResponse response = httpClient.execute(httpget)) {
                HttpEntity entity = response.getEntity();

                System.out.println("----------------------------------------");
                System.out.println(response.getStatusLine());
                if (entity != null) {
                    System.out.println("Response content length: " + entity.getContentLength());
                    System.out.printf(EntityUtils.toString(entity));
                }
                EntityUtils.consume(entity);
            }
        }
    }
}

谢谢

java ssl httpclient apache-httpclient-4.x
1个回答
0
投票

JRE 11不是问题,但它默认使用的TLSv1.3是。已经测试了Apache HttpClient 5.0与JRE 11 TLSv1.3的兼容性,但HttpClient 4.5没有。现在只是强制使用TLSv1.2,问题应该消失。

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