Apache http 客户端自签名证书
Apache http client self signed cert
我正在尝试通过 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();
}
}
从问题中不清楚你想要达到什么。
如果您需要为“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
方法,而不是使用默认方法 (f.e., 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();
我正在尝试通过 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();
}
}
从问题中不清楚你想要达到什么。
如果您需要为“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
方法,而不是使用默认方法 (f.e., 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();