Apache HTTP客户端自签名证书

时间:2019-12-27 10:49:29

标签: java apache http ssl self-signed

我正在尝试通过Apache HTTP客户端向Web服务发出HTTP请求,但是我收到了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

我按照以下建议进行了测试,但仍然遇到相同的错误。我错过了什么吗? https://memorynotfound.com/ignore-certificate-errors-apache-httpclient/

import org.apache.http.client.methods.HttpGet;
import org.apache.http.conn.ssl.*;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContextBuilder;
import javax.net.ssl.*;
import java.io.IOException;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;

public class TestHttpSSL {

    public static void main(String... args)  {

        try (CloseableHttpClient httpclient = createAcceptSelfSignedCertificateClient()) {
            HttpGet httpget = new HttpGet("https://myurl/");
            System.out.println("Executing request " + httpget.getRequestLine());

            httpclient.execute(httpget);
            System.out.println("----------------------------------------");
        } catch (NoSuchAlgorithmException | KeyStoreException | KeyManagementException | IOException e) {
            throw new RuntimeException(e);
        }
    }

    private static CloseableHttpClient createAcceptSelfSignedCertificateClient()
            throws KeyManagementException, NoSuchAlgorithmException, KeyStoreException {

        SSLContext sslContext = SSLContextBuilder
                .create()
                .loadTrustMaterial(new TrustSelfSignedStrategy())
                .build();

        HostnameVerifier allowAllHosts = new NoopHostnameVerifier();

        SSLConnectionSocketFactory connectionFactory = new SSLConnectionSocketFactory(sslContext, allowAllHosts);

        return HttpClients
                .custom()
                .setSSLSocketFactory(connectionFactory)
                .build();
    }
}

1 个答案:

答案 0 :(得分:0)

从问题中不清楚您想要实现什么。

如果您需要对“ https://myurl/”使用自签名证书,则应向信任库提供此证书。示例(假设您已将证书放置到resources文件夹中,并将其路径分配给certPath变量,并将其密码分配给certPassword):

KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
byte[] certificate = IOUtils.toByteArray(this.getClass().getResourceAsStream(certPath));
ByteArrayInputStream bis = new ByteArrayInputStream(certificate);
trustStore.load(bis, certPassword.toCharArray());

在这里,IOUtils用于将输入流转换为字节数组以简化操作,但是您可以手动进行操作。您可以选择将证书类型传递给getInstance方法,而不是使用默认方法(例如KeyStore.getInstance("PKCS12");

然后在创建SSLContext时使用准备好的信任库:

SSLContext sslContext = SSLContextBuilder
        .create()
        .loadTrustMaterial(trustStore, new TrustSelfSignedStrategy())
        .build();

相反,如果您想完全禁用SSL检查,则可以使用the another strategy-TrustAllStrategy。在这种情况下,您根本不需要设置任何信任库。示例:

SSLContext sslContext = SSLContextBuilder
        .create()
        .loadTrustMaterial(null, new TrustAllStrategy())
        .build();