HttpClient之配置ssl,采用设置信任自签名证书实现https

在上篇文章《HttpClient配置ssl实现https简单示例——绕过证书验证》中简单分享了一下如何绕过证书验证。如果你想用httpclient访问一个网站,但是对方的证书没有通过ca认证或者其他问题导致证书不被信任,比如12306的证书就是这样的。所以对于这样的情况,你只能是选择绕过证书验证的方案了。

但是,如果是自己用jdk或者其他工具生成的证书,还是希望用其他方式认证自签名的证书,这篇文章就来分享一下如何设置信任自签名的证书。当然你也可以参考官网示例中。

要想信任自签名的证书,必须得知道密钥库的路径及密钥库的密码。然后加载到程序来才可以。具体代码如下:

 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
/**
  * 设置信任自签名证书
 
  * @param keyStorePath      密钥库路径
  * @param keyStorepass      密钥库密码
  * @return
  */
public static SSLContext custom(String keyStorePath, String keyStorepass){
     SSLContext sc = null ;
     FileInputStream instream = null ;
     KeyStore trustStore = null ;
     try {
         trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
         instream = new FileInputStream( new File(keyStorePath));
         trustStore.load(instream, keyStorepass.toCharArray());
         // 相信自己的CA和所有自签名的证书
         sc = SSLContexts.custom().loadTrustMaterial(trustStore, new TrustSelfSignedStrategy()).build();
     } catch (KeyStoreException | NoSuchAlgorithmException| CertificateException | IOException | KeyManagementException e) {
         e.printStackTrace();
     } finally {
         try {
             instream.close();
         } catch (IOException e) {
         }
     }
     return sc;
}
然后修改原来的send方法:
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
     /**
      * 模拟请求
      *
      * @param url       资源地址
      * @param map   参数列表
      * @param encoding  编码
      * @return
      * @throws ParseException
      * @throws IOException
      * @throws KeyManagementException
      * @throws NoSuchAlgorithmException
      * @throws ClientProtocolException
      */
     public static String send(String url, Map<string,string> map,String encoding) throws ClientProtocolException, IOException {
         String body = ;
         
         //tomcat是我自己的密钥库的密码,你可以替换成自己的
         //如果密码为空,则用nopassword代替
         SSLContext sslcontext = custom(D:\keys\wsriakey, tomcat);
         
         // 设置协议http和https对应的处理socket链接工厂的对象
         Registry<connectionsocketfactory> socketFactoryRegistry = RegistryBuilder.<connectionsocketfactory>create()
             .register(http, PlainConnectionSocketFactory.INSTANCE)
             .register(https, new SSLConnectionSocketFactory(sslcontext))
             .build();
         PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
         HttpClients.custom().setConnectionManager(connManager);
 
         //创建自定义的httpclient对象
         CloseableHttpClient client = HttpClients.custom().setConnectionManager(connManager).build();
//      CloseableHttpClient client = HttpClients.createDefault();
         
         //创建post方式请求对象
         HttpPost httpPost = new HttpPost(url);
         
         //装填参数
         List<namevaluepair> nvps = new ArrayList<namevaluepair>();
         if (map!= null ){
             for (Entry<string, string= "" > entry : map.entrySet()) {
                 nvps.add( new BasicNameValuePair(entry.getKey(), entry.getValue()));
             }
         }
         //设置参数到请求对象中
         httpPost.setEntity( new UrlEncodedFormEntity(nvps, encoding));
 
         System.out.println(请求地址:+url);
         System.out.println(请求参数:+nvps.toString());
         
         //设置header信息
         //指定报文头【Content-type】、【User-Agent】
         httpPost.setHeader(Content-type, application/x-www-form-urlencoded);
         httpPost.setHeader(User-Agent, Mozilla/ 4.0 (compatible; MSIE 5.0 ; Windows NT; DigExt));
         
         //执行请求操作,并拿到结果(同步阻塞)
         CloseableHttpResponse response = client.execute(httpPost);
         //获取结果实体
         HttpEntity entity = response.getEntity();
         if (entity != null ) {
             //按指定编码转换结果实体为String类型
             body = EntityUtils.toString(entity, encoding);
         }
         EntityUtils.consume(entity);
         //释放链接
         response.close();
         return body;
     }</string,></namevaluepair></namevaluepair></connectionsocketfactory></connectionsocketfactory></string,string>
测试一下吧:
?
1
2
3
4
5
6
7
8
9
10
11
public static void main(String[] args) throws ParseException, IOException, KeyManagementException, NoSuchAlgorithmException{
     String url = https: //sso.tgb.com:8443/cas/login;
     String body = send(url, null , utf- 8 );
     System.out.println(交易响应结果长度:+body.length());
     
     System.out.println(-----------------------------------);
     
     url = https: //kyfw.12306.cn/otn/;
     body = send(url, null , utf- 8 );
     System.out.println(交易响应结果长度:+body.length());
}
测试结果:

 

width=906

从结果中,我们很清楚的看到,使用自签名的证书,访问自签名的网站可以正常访问,访问12306则会失败。所以自签名的也只能用于自定义密钥和证书的情况下使用。而12306这种情况还是要用上一篇提到的“绕过证书验证”方案。


http://www.2cto.com/kf/201511/450707.html

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值