java.net.http.HttpClient信任所有证书并关闭主机名验证

时间:2019-10-23 14:55:50

标签: java ssl https client truststore

!注意。这不是用于生产环境,我完全理解这一点。

当前,我们使用org.apache.httpcomponents HttpClient进行“轻松”修改的可能性。我们这样修改:

    // Remove certificate validation
    TrustStrategy acceptingTrustStrategy = (X509Certificate[] chain, String authType) -> true;

    SSLContext sslContext = SSLContexts.custom()
            .loadTrustMaterial(null, acceptingTrustStrategy).build();

    HttpClientBuilder builder = HttpClients.custom();
    builder.setSSLHostnameVerifier(new NoopHostnameVerifier()); // Remove Host validation
    builder.setSSLContext(sslContext);

    CloseableHttpClient httpClient = builder.build();

但是,我想转到标准Java 11 HttpClient。我已经读过Java Secure Socket Extension (JSSE) Reference Guide,但对我来说如何修改SSLContext尚不清楚。 到目前为止,我有:

    // Remove certificate validation
    SSLContext sslContext = null;

    TrustManager[] trustAllCerts = new TrustManager[]{
            new X509TrustManager() {

                @Override
                public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                    return null;
                }

                @Override
                public void checkClientTrusted(
                        java.security.cert.X509Certificate[] certs, String authType) {
                }

                @Override
                public void checkServerTrusted(
                        java.security.cert.X509Certificate[] certs, String authType) {
                }
            }
    };

    try {
        sslContext = SSLContext.getInstance("TLS");
        sslContext.init(null, trustAllCerts, new SecureRandom());
    } catch (NoSuchAlgorithmException | KeyManagementException e) {
        e.printStackTrace();
    }

我认为这从根本上解决了我的第一个问题-信任所有证书。但是,如何关闭主机名验证?深入研究apache源代码,我只能在 SSLContext 的一部分 SSLConnectionSocketFactory 中修改主机名验证程序。这是否意味着我应该创建新的SSLConnectionSocketFactory并分配HostnameVerifier,如下所示:

        final String[] supportedProtocols = System.getProperty("https.protocols").split(",");
        final String[] supportedCipherSuites = System.getProperty("https.cipherSuites").split(",");
        var sslSocketFactoryCopy = new SSLConnectionSocketFactory(
                sslContext, supportedProtocols, supportedCipherSuites, new HostnameVerifier() {
            @Override
            public boolean verify(String hostname, SSLSession session) {
                return true;
            }
        });

但是如何将其分配给SSLContext?对于代码的任何部分,如果您有更好的建议-请不要犹豫。

编辑。修改HttpClient sslContext:

HttpClient.newBuilder()
            .sslContext(sslcontext)
            .build();

0 个答案:

没有答案