当前位置: 首页 > 面试题库 >

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

公西国发
2023-03-14
问题内容

我知道,关于这个问题有很多不同的问题和很多答案…但是我听不懂…

我已经:从关闭“按原样”安装了ubuntu-9.10-desktop-amd64 + NetBeans6.7.1。代表 我需要通过HTTPS连接到某个站点。为此,我使用Apache的HttpClient。

教程中我读到:

“一旦正确安装了JSSE,通过SSL的安全HTTP通信就应该
与普通HTTP通信一样简单。” 还有一些例子:

HttpClient httpclient = new HttpClient();
GetMethod httpget = new GetMethod("https://www.verisign.com/"); 
try { 
  httpclient.executeMethod(httpget);
  System.out.println(httpget.getStatusLine());
} finally {
  httpget.releaseConnection();
}

现在,我写这个:

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();
}

结果,我有一系列错误:

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和Trust Manager等。)


问题答案:

你需要执行以下操作之一:

  • 使用接受任何证书的TrustManager配置SSLContext(请参阅下文)
  • 使用包含你的证书的适当信任库配置SSLContext
  • 将该站点的证书添加到默认的Java信任库中。

这是一个示例程序,该程序创建一个接受任何证书的(几乎一文不值的)SSL上下文:

import java.net.URL;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.KeyManager;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

public class SSLTest {

    public static void main(String [] args) throws Exception {
        // configure the SSLContext with a TrustManager
        SSLContext ctx = SSLContext.getInstance("TLS");
        ctx.init(new KeyManager[0], new TrustManager[] {new DefaultTrustManager()}, new SecureRandom());
        SSLContext.setDefault(ctx);

        URL url = new URL("https://mms.nw.ru");
        HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
        conn.setHostnameVerifier(new HostnameVerifier() {
            @Override
            public boolean verify(String arg0, SSLSession arg1) {
                return true;
            }
        });
        System.out.println(conn.getResponseCode());
        conn.disconnect();
    }

    private static class DefaultTrustManager implements X509TrustManager {

        @Override
        public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {}

        @Override
        public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {}

        @Override
        public X509Certificate[] getAcceptedIssuers() {
            return null;
        }
    }
}


 类似资料:
  • 我的公司将Maven依赖项保留在具有无效SSL证书的服务器上。我们必须使用https进行连接。当我尝试运行Maven时,它无法下载资源。 我知道我要访问的站点的名称。我很乐意为该站点添加一个安全异常,或者关闭所有ssl证书的验证,以便所有https站点都被视为有效。 我正在使用Maven 3.0.4。 以下是我尝试构建时堆栈跟踪的一些亮点: ...

  • 我正在使用Selenium启动浏览器。如何处理要求浏览器接受或不接受证书的网页(URL)? 在Firefox中,我可能会有这样一个网站,要求我接受它的证书,如下所示: 在Internet Explorer浏览器上,我可能会得到如下内容: 在谷歌Chrome: 我重复我的问题:当我使用Selenium(Python编程语言)启动浏览器(internetexplorer、Firefox和googlec

  • 问题内容: 我正在使用MATLAB的命令访问内部数据库,直到将服务移至安全服务器(即使用HTTPS地址而不是HTTP地址)之前,一切工作正常。现在不再成功检索结果。它给出一个错误: 下载网址时出错。您的网络连接可能已断开,或者您的代理设置配置不正确。 我认为问题在于该服务正在使用无效的数字证书,因为如果我尝试直接在Web浏览器中访问资源,则会收到“不受信任的连接”警告,我可以通过将该站点添加到“例

  • 问题内容: 我使用 Selenium来 启动浏览器。如何处理要求浏览器接受证书的网页(URL)? 我重复我的问题: 当我启动 使用Selenium(Python编程语言)的浏览器(Internet Explorer,Firefox和Google Chrome)时,如何自动接受网站的证书? 问题答案: 对于Firefox,您需要将 选项设置为 : 对于Chrome,您需要添加参数 argument:

  • 这应该很容易做到。我可以在Guzze3中找到很多关于如何做到这一点的参考资料,但是它们在Guzze5中不起作用。 我目前正在做的事情: 当我发送请求时,我收到了这个错误: 我在谷歌上找不到任何关于这个错误的有用参考。如果我可以访问旋度选项,那么我可以尝试类似这里建议的解决方案(这是针对Guzzle 3的,因此它不起作用):http://inchoo.net/dev-talk/symfony2-gu

  • 线程“main”javax.net.ssl.SSLHandShakeException中的异常:没有共同的密码套件 列出的密码如下