有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java Apache Http客户端SSL证书错误

我知道以前有人问过,但我尝试了我找到的所有解决方案,但仍然不起作用

基本上,我试图通过ApacheHTTP客户端(4.3)获取一些内容,而我连接的网站存在一些SSL问题

首先,我得到和SSLExceptionunrecognized_name消息。我试图通过将jsse.enableSNIExtension属性设置为false来解决这个问题

然后,我得到了一个例外: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

然后我尝试提供接受所有证书的wonSSLFactory,但仍然得到相同的异常。这是我的密码:

private static void sslTest() throws Exception {
    System.setProperty("jsse.enableSNIExtension", "false");

    SSLContext sslContext = SSLContexts.custom()
            .loadTrustMaterial(null, new TrustSelfSignedStrategy())
            .useTLS()
            .build();

    SSLConnectionSocketFactory connectionFactory =
            new SSLConnectionSocketFactory(sslContext, new AllowAllHostnameVerifier());

    CookieStore cookieStore = new BasicCookieStore();
    HttpClientContext context = HttpClientContext.create();
    context.setCookieStore(cookieStore);

    CloseableHttpClient httpclient = HttpClients.custom()
            .setSSLSocketFactory(connectionFactory)
            .setDefaultCookieStore(cookieStore)
            .build();

    URI uri = new URIBuilder()
            .setScheme("https")
            .setHost(BASE_URL)
            .build();

    String responseBody = httpclient.execute(new HttpGet(uri), RESPONSE_HANDLER);
}

非常感谢您的帮助


共 (4) 个答案

  1. # 1 楼答案

    下面是Apache4x信任一切的例子

    static {
        // avoid error javax.net.ssl.SSLProtocolException: handshake alert:  unrecognized_name
        System.setProperty("jsse.enableSNIExtension", "false");
    }
    
    public static HttpClientBuilder createTrustAllHttpClientBuilder() {
        try {
            SSLContextBuilder builder = new SSLContextBuilder();
            builder.loadTrustMaterial(null, (chain, authType) -> true);
            SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(builder.build(), NoopHostnameVerifier.INSTANCE);
    
            return HttpClients.custom().setSSLSocketFactory(sslsf);
        }
        catch (KeyManagementException | NoSuchAlgorithmException | KeyStoreException e) {
            throw new IllegalStateException(e);
        }
    }
    
  2. # 2 楼答案

    在Http客户端4.5.2中:

    SSLContext sslContext = SSLContexts.custom().loadTrustMaterial(null, 
        new TrustStrategy() {
            @Override
            public boolean isTrusted(final X509Certificate[] chain, final String authType) 
            throws CertificateException {
                return true;
            }
        }).build();
    
    SSLConnectionSocketFactory sslsf;
    sslsf = new SSLConnectionSocketFactory(sslContext, NoopHostnameVerifier.INSTANCE);
    

    然后:

    HttpClientBuilder builder = HttpClients.custom().setSSLSocketFactory(sslsf);
    
  3. # 3 楼答案

    还请注意,信任自签名证书并不意味着信任任何任意证书

    尝试以下方式设置SSL上下文:

    SSLContext sslContext = SSLContexts.custom().loadTrustMaterial(null, 
        new TrustStrategy() {
            @Override
            public boolean isTrusted(final X509Certificate[] chain, final String authType) 
            throws CertificateException {
                return true;
            }
        })
        .useTLS()
        .build();
    

    还请注意,通常不加区别地信任证书首先会破坏使用SSL的目的。在绝对必要或仅用于测试时使用

  4. # 4 楼答案

    您的信任库不信任服务器证书

    允许所有主机名是一个HTTPS步骤,只有在证书受信任的情况下才能调用该步骤