亲测,很有效的忽略SSL证书方法

1.在httpclient发起请求时,有时会出现下面这种情况

    你的日志中出现有关SSL的异常,javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated,我们会注意到SSL这几个字母,这是和https提交时有关的地方。

2.什么是SSL证书

       SSL证书,也称为服务器SSL证书,是遵守SSL协议的一种数字证书,由全球信任的证书颁发机构(CA)验证服务器身份后颁发。将SSL证书安装在网站服务器上,可实现网站身份验证和数据加密传输双重功能,有效防止机密数据在传输过程中被窃取和纂改,有效防止钓鱼网站浑水摸鱼盗取用户财产。

3.解决方法--忽略SSL证书

3.1忽略SSL证书的流程

  • 简介:需要告诉client使用一个不同的TrustManager。TrustManager是一个检查给定的证书是否有效的类。SSL使用的模式是X.509,对于该模式Java有一个特定的TrustManager,称为X509TrustManager。首先我们需要创建这样的TrustManager。将TrustManager设置到我们的HttpClient。TrustManager只是被SSL的Socket所使用。Socket通过SocketFactory创建。对于SSL Socket,有一个SSLSocketFactory。当创建新的SSLSocketFactory时,你需要传入SSLContext到它的构造方法中。在SSLContext中,我们将包含我们新创建的TrustManager。
  1. 创建的TrustManager
  2. 创建SSLContext:TLS是SSL的继承者,但是它们使用相同的SSLContext。
  3. 创建SSLSocketFactory
  4. 将SSLSocketFactory注册到我们的HttpClient上。这是在SchemeRegistry中完成的。
  5. 创建ClientConnectionManager,创建SchemeRegistry。
  6. 生成HttpClient

3.2代码实现

 1 import java.security.cert.CertificateException;
 2 import java.security.cert.X509Certificate;
 3 
 4 import javax.net.ssl.SSLContext;
 5 import javax.net.ssl.TrustManager;
 6 import javax.net.ssl.X509TrustManager;
 7 
 8 import org.apache.http.client.HttpClient;
 9 import org.apache.http.conn.ClientConnectionManager;
10 import org.apache.http.conn.scheme.Scheme;
11 import org.apache.http.conn.scheme.SchemeRegistry;
12 import org.apache.http.conn.ssl.SSLSocketFactory;
13 import org.apache.http.impl.client.DefaultHttpClient;
14 
15 public class WebClientDevWrapper {
16 
17     public static HttpClient wrapClient(HttpClient base) {
18         try {
19             SSLContext ctx = SSLContext.getInstance("TLS");
20             X509TrustManager tm = new X509TrustManager() {
21                 public X509Certificate[] getAcceptedIssuers() {
22                     return null;
23                 }
24                 public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {}
25                 public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {}
26             };
27             ctx.init(null, new TrustManager[] { tm }, null);
28             SSLSocketFactory ssf = new SSLSocketFactory(ctx, SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
29             
30             ClientConnectionManager ccm=base.getConnectionManager();
31             SchemeRegistry registry = ccm.getSchemeRegistry();
32             registry.register(new Scheme("https", 443, ssf));
33             return new DefaultHttpClient(ccm, base.getParams());
34             
35            /* SchemeRegistry registry = new SchemeRegistry();
36             registry.register(new Scheme("https", 443, ssf));
37             ThreadSafeClientConnManager mgr = new ThreadSafeClientConnManager(registry);
38             return new DefaultHttpClient(mgr, base.getParams());*/
39         } catch (Exception ex) {
40             ex.printStackTrace();
41             return null;
42         }
43     }
44 }

对应的httpclient提交为:

HttpClient httpClient = WebClientDevWrapper.wrapClient(new DefaultHttpClient());
HttpPost post = new HttpPost(url);

注:这里有一点要说明,有的时候即使加入这段代码也还是会抛异常,个人在查找资料的时候发现,javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated,这种异常还与jdk版本有关,在上边代码的第19行(TLS),这里可以换上与你jdk环境相对应的通信协议TLSv:

  1. jdk6默认对应的是TLSv1;但还可以是TLSv1.1和SSLv3。
  2. jdk7默认对应的是TLSv1;但还可以是TLSv1.1、TLSv1.2和SSLv3。
  3. jdk3默认对应的是TLSv1.2;但还可以是TLSv、TLSv1.1和SSLv3。

所以要根据自身的实际情况更改对应的通信协议。

猜你喜欢

转载自www.cnblogs.com/jiaxiaoyang/p/10017103.html