首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何使用Apache HttpClient处理无效的SSL证书?

如何使用Apache HttpClient处理无效的SSL证书?
EN

Stack Overflow用户
提问于 2009-12-02 04:40:32
回答 13查看 339.2K关注 0票数 129

我知道,关于这个问题有很多不同的问题和答案……但我不明白。

我已经安装了:ubuntu-9.10- from amd64+ NetBeans6.7.1。代表我需要通过HTTPS连接到一些网站。为此,我使用Apache的HttpClient。

从教程中我读到:

“正确安装JSSE后,SSL上的安全HTTP通信应为

简单如普通的HTTP通信。“和一些例子:

代码语言:javascript
复制
HttpClient httpclient = new HttpClient();
GetMethod httpget = new GetMethod("https://www.verisign.com/"); 
try { 
  httpclient.executeMethod(httpget);
  System.out.println(httpget.getStatusLine());
} finally {
  httpget.releaseConnection();
}

到目前为止,我这样写道:

代码语言:javascript
复制
HttpClient client = new HttpClient();

HttpMethod get = new GetMethod("https://mms.nw.ru");
//get.setDoAuthentication(true);

try {
    int status = client.executeMethod(get);
    System.out.println(status);

    BufferedInputStream is = new BufferedInputStream(get.getResponseBodyAsStream());
    int r=0;byte[] buf = new byte[10];
    while((r = is.read(buf)) > 0) {
        System.out.write(buf,0,r);
    }

} catch(Exception ex) {
    ex.printStackTrace();
}

因此,我有一组错误:

代码语言:javascript
复制
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
        at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
        at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1627)
        at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:204)
        at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:198)
        at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:994)
        at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:142)
        at sun.security.ssl.Handshaker.processLoop(Handshaker.java:533)
        at sun.security.ssl.Handshaker.process_record(Handshaker.java:471)
        at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:904)
        at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1132)
        at sun.security.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:643)
        at sun.security.ssl.AppOutputStream.write(AppOutputStream.java:78)
        at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:82)
        at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:140)
        at org.apache.commons.httpclient.HttpConnection.flushRequestOutputStream(HttpConnection.java:828)
        at org.apache.commons.httpclient.HttpMethodBase.writeRequest(HttpMethodBase.java:2116)
        at org.apache.commons.httpclient.HttpMethodBase.execute(HttpMethodBase.java:1096)
        at org.apache.commons.httpclient.HttpMethodDirector.executeWithRetry(HttpMethodDirector.java:398)
        at org.apache.commons.httpclient.HttpMethodDirector.executeMethod(HttpMethodDirector.java:171)
        at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:397)
        at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:323)
        at simpleapachehttp.Main.main(Main.java:41)
Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
        at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:302)
        at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:205)
        at sun.security.validator.Validator.validate(Validator.java:235)
        at sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:147)
        at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:230)
        at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:270)
        at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:973)
        ... 17 more
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
        at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:191)
        at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:255)
        at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:297)
        ... 23 more

如何创建最简单的SSL连接?(可能没有KeyManager和信任管理器等。)

EN

回答 13

Stack Overflow用户

发布于 2012-05-02 08:31:49

除了Pascal Thivent的正确答案之外,另一种方法是保存来自Firefox (查看证书->详细信息->导出)或openssl s_client的证书,并将其导入到信任存储中。

只有当您有办法验证该证书时,才应该这样做。如果做不到这一点,请在第一次连接时执行此操作,如果证书在后续连接中意外更改,则至少会给您一个错误。

要将其导入信任存储区,请使用:

代码语言:javascript
复制
keytool -importcert -keystore truststore.jks -file servercert.pem

默认情况下,默认信任存储区应为$JAVA_HOME/jre/lib/security/cacerts,其密码应为changeit,有关详细信息,请参阅JSSE Reference guide

如果您不想全局允许该证书,但只允许这些连接使用,则可以为其创建一个SSLContext

代码语言:javascript
复制
TrustManagerFactory tmf = TrustManagerFactory
    .getInstance(TrustManagerFactory.getDefaultAlgorithm());
KeyStore ks = KeyStore.getInstance("JKS");
FileInputStream fis = new FileInputStream("/.../truststore.jks");
ks.load(fis, null);
// or ks.load(fis, "thepassword".toCharArray());
fis.close();

tmf.init(ks);

SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, tmf.getTrustManagers(), null);

然后,您需要为Apache HTTP client3.x设置它,如果它的SecureProtocolSocketFactory使用此SSLContext,则需要实现一个one。(有here的例子)。

Apache HTTP Client 4.x (除了最早的版本)直接支持传递SSLContext

票数 23
EN

Stack Overflow用户

发布于 2009-12-02 04:53:35

来自http://hc.apache.org/httpclient-3.x/sslguide.html

代码语言:javascript
复制
Protocol.registerProtocol("https", 
new Protocol("https", new MySSLSocketFactory(), 443));
HttpClient httpclient = new HttpClient();
GetMethod httpget = new GetMethod("https://www.whatever.com/");
try {
  httpclient.executeMethod(httpget);
      System.out.println(httpget.getStatusLine());
} finally {
      httpget.releaseConnection();
}

here中可以找到MySSLSocketFactory示例。它引用了一个TrustManager,您可以对其进行修改以信任所有内容(尽管您必须考虑这一点!)

票数 10
EN

Stack Overflow用户

发布于 2019-02-15 17:29:10

我想在这里粘贴答案:

在Apache HttpClient 4.5.5中

How to handle invalid SSL certificate with Apache client 4.5.5?

代码语言:javascript
复制
HttpClient httpClient = HttpClients
            .custom()
            .setSSLContext(new SSLContextBuilder().loadTrustMaterial(null, TrustAllStrategy.INSTANCE).build())
            .setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE)
            .build();
票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1828775

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档