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

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

我已经:从关闭“按原样”安装了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;

}

}

}

以上是 如何使用Apache HttpClient处理无效的SSL证书? 的全部内容, 来源链接: utcz.com/qa/416446.html

回到顶部