您的位置:首页 > 理论基础 > 计算机网络

java实现 HTTP/HTTPS请求绕过证书检测代码实现

2017-06-21 10:55 771 查看


1、开发需求

需要实现在服务端发起HTTP/HTTPS请求,访问其他程序资源。


2、URLConnection和HTTPClient的比较

HttpClient是个很不错的开源框架,封装了访问http的请求头,参数,内容体,响应等等,
DefaultHttpClient和它的兄弟AndroidHttpClient都是HttpClient具体的实现类,它们都拥有众多的API,而且实现比较稳定,bug数量也很少。


3、使用Apache的HttpClient发送GET和POST请求

1. 使用帮助类HttpClients创建CloseableHttpClient对象.
2. 基于要发送的HTTP请求类型创建HttpGet或者HttpPost实例.
3. 使用addHeader方法添加请求头部,诸如User-Agent, Accept-Encoding等参数.
4. 对于POST请求,创建NameValuePair列表,并添加所有的表单参数.然后把它填充进HttpPost实体.
5. 通过执行此HttpGet或者HttpPost请求获取CloseableHttpResponse实例
6. 从此CloseableHttpResponse实例中获取状态码,错误信息,以及响应页面等等.
7. 最后关闭HttpClient资源.
1
2
3
4
5
6
7
1
2
3
4
5
6
7


4、SSL与TLS的区别以及介绍

SSL
SSL是Netscape公司所提出的安全保密协议,在浏览器(如Internet Explorer、Netscape Navigator)和Web服务器(如Netscape的Netscape Enterprise Server、ColdFusion Server等等)之间构造安全通道来进行数据传输,SSL运行在TCP/IP层之上、应用层之下,为应用程序提供加密数据通道,它采用了RC4、MD5以及RSA等加密算法,使用40 位的密钥,适用于商业信息的加密。
同时,Netscape公司相应开发了HTTPS协议并内置于其浏览器中。
HTTPS实际上就是HTTP over SSL,它使用默认端口443,而不是像HTTP那样使用端口80来和TCP/IP进行通信。
HTTPS协议使用SSL在发送方把原始数据进行加密,然后在接受方进行解密,加密和解密需要发送方和接受方通过交换共知的密钥来实现,因此,所传送的数据不容易被网络黑客截获和解密。 然而,加密和解密过程需要耗费系统大量的开销,严重降低机器的性能,相关测试数据表明使用HTTPS协议传输数据的工作效率只有使用HTTP协议传输的十分之一。假如为了安全保密,将一个网站所有的Web应用都启用SSL技术来加密,并使用HTTPS协议进行传输,那么该网站的性能和效率将会大大降低,而且没有这个必要,因为一般来说并不是所有数据都要求那么高的安全保密级别。

TLS
安全传输层协议
  TLS:Transport Layer Security
  安全传输层协议(TLS)用于在两个通信应用程序之间提供保密性和数据完整性。该协议由两层组成: TLS 记录协议(TLS Record)和 TLS 握手协议(TLS Handshake)。较低的层为 TLS 记录协议,位于某个可靠的传输协议(例如 TCP)上面。
1
2
3
4
5
6
7
8
9
10
1
2
3
4
5
6
7
8
9
10


5、 post请求封装的工具类

import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.Method;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import com.sun.corba.se.impl.orbutil.threadpool.TimeoutException;
import org.apache.commons.httpclient.util.TimeoutController;
import org.apache.http.NameValuePair;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.apache.log4j.Logger;
import cn.qtone.hjy.service.bean.yd.sync.AccountPasswordInfoSyncItem;
import cn.qtone.hjy.service.bean.yd.sync.OrderInfoSyncItem;
import cn.qtone.hjy.service.bean.yd.sync.YdOrderRelationshipInfoSyncItem;
import cn.qtone.hjy.service.core.DES;
import cn.qtone.hjy.service.dao.YdEduDao;
import cn.qtone.util.SpringUtil;
import com.alibaba.fastjson.JSONObject;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

public class HttpClientUtil {

static Logger log = Logger.getLogger(HttpClientUtil.class) ;

private static  RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(10000).setConnectTimeout(10000).build();//设置请求和传输超时时间

private static CloseableHttpClient httpclient = HttpClients.createDefault();

public static String send(String httpUrl, String message) throws IOException {
String result = null ;
HttpPost httpPost = new HttpPost(httpUrl);
//设置数据读取超时5s   传输超时5s    链接请求超时5s
RequestConfig requestConfig = RequestConfig.custom()
.setSocketTimeout(5000)
.setConnectTimeout(5000)
.setConnectionRequestTimeout(5000)
.build();
httpPost.setConfig(requestConfig) ;
message = URLEncoder.encode(message, "UTF-8") ;
StringEntity entity = new StringEntity(message);
httpPost.setEntity(entity);
CloseableHttpResponse response = httpclient.execute(httpPost);
BufferedReader in = null ;
try {
InputStream content = response.getEntity().getContent() ;
in = new BufferedReader(new InputStreamReader(content));
StringBuilder sb = new StringBuilder();
String line = "" ;
while ((line = in.readLine()) != null) {
sb.append(line);
}
result = sb.toString() ;
System.out.println("接收原始报文:" + URLDecoder.decode(result, "UTF-8")) ;
} finally {
EntityUtils.consume(response.getEntity());
response.close();
}
return result ;
}

public static String post(String httpUrl, String message) throws Exception {
String result = null ;
CloseableHttpClient httpclient = HttpClients.createDefault();
BufferedReader in = null ;
HttpPost httpPost = new HttpPost(httpUrl);
httpPost.setConfig(requestConfig);
List <NameValuePair> nvps = new ArrayList <NameValuePair>();
nvps.add(new BasicNameValuePair("tokenId", DES.encrypt(message)));
httpPost.setEntity(new UrlEncodedFormEntity(nvps));
try {
System.out.println("发送报文:" + message);
System.out.println("发送报文:" + DES.encrypt(message)) ;
CloseableHttpResponse response = httpclient.execute(httpPost);
InputStream content = response.getEntity().getContent() ;
in = new BufferedReader(new InputStreamReader(content, "UTF-8"));
StringBuilder sb = new StringBuilder();
String line = "" ;
while ((line = in.readLine()) != null) {
sb.append(line);
}
System.out.println("响应报文:" + sb.toString()) ;
//result = URLDecoder.decode(sb.toString(), "UTF-8") ;
//result = DES.decrypt(result) ;
//System.out.println("完成:" + JSONObject.parseObject(result) + "\n");
return result ;
} catch (Exception e) {
e.printStackTrace() ;
} finally {
httpclient.close();
}
return null ;
}

/**
* 发起post请求,请求参数以Map集合形式传入,封装到List <NameValuePair> 发起post请求
* @param httpUrl
* @param params
* @return
* @throws Exception
*/
public static String post(String httpUrl, Map<String, String> params) throws Exception {
String result = null ;
CloseableHttpClient httpclient = createSSLClientDefault();
//httpclient.
//httpclient.
BufferedReader in = null ;
HttpPost httpPost = new HttpPost(httpUrl);
httpPost.setConfig(requestConfig);
List <NameValuePair> nvps = new ArrayList <NameValuePair>();
StringBuffer paramsBuf = new StringBuffer() ;
for(Entry<String, String> e : params.entrySet()) {
nvps.add(new BasicNameValuePair(e.getKey(), e.getValue()));
paramsBuf.append("&").append(e.getKey()).append("=").append(e.getValue()) ;
}
httpPost.setEntity(new UrlEncodedFormEntity(nvps, "UTF-8"));
try {
//          报文参数27:&id=jn-3-767744&groupPlatProTerminalId=119667&extend=uwJZ8j3CkpGPL4rM5J6KJhjR99O7yAe3BAGLS8ooI8ijNqKHfzTaK6W9wQvjZEVOmWJ3HxFb2O9D
//          wDbe3++UiQ==&xxtCode=370000&terminalType=1&role=3&type=3
System.out.println("post请求报文地址:" + httpUrl+"?"+paramsBuf.toString()) ;
CloseableHttpResponse response = httpclient.execute(httpPost);
InputStream content = response.getEntity().getContent() ;
in = new BufferedReader(new InputStreamReader(content, "UTF-8"));
//          in = new BufferedReader(new InputStreamReader(content, "GBK"));
//          in = new BufferedReader(new InputStreamReader(content));
StringBuilder sb = new StringBuilder();
String line = "" ;
while ((line = in.readLine()) != null) {
sb.append(line);
}
result = sb.toString() ;
System.out.println("响应报文:" + result) ;
//  响应报文:{"ret":0,"msg":"成功","callbackurl":"https://edu.10086.cn/test-sso/login?service=http%3A%2F%2F112.35.7.169%3A9010%2Feducloud%2Flogin%2Flogin%3Ftype%3D3%26mode%3D1%26groupId%3D4000573%26provincePlatformId%3D54","accesstoken":"2467946a-bee9-4d8c-8cce-d30181073b75"}Í
//记录报文日志
YdEduDao dao = SpringUtil.getBean(YdEduDao.class);
dao.saveCallLog(httpUrl, paramsBuf.toString(), result);    // HJY_SERVICE_LOG

return result ;
} catch (Exception e) {
e.printStackTrace() ;
} finally {
httpclient.close();
}
return null ;
}

public static JSONObject postData(String httpUrl, Object obj) throws Exception {
JSONObject json = null;
try{
String result = post(httpUrl,obj);
json = JSONObject.parseObject(result);
}catch(TimeoutException e){
System.out.println("请求超时了:"+httpUrl);
throw e;
}finally {
return json ;
}
}

public static String post(String httpUrl, Object obj) throws Exception {
Map<String, String>  params = getParamData(obj);
String result = null ;

try {
result = post(httpUrl,params);
return result ;
} catch (Exception e) {
e.printStackTrace() ;
} finally {
httpclient.close();
}
return null ;
}

private static Map<String, String>  getParamData(Object obj) {

Class cla = obj.getClass();
Map<String, String> map = new HashMap<String, String>();
Method[] methods = cla.getDeclaredMethods();
try {
for (Method m : methods) {
String mname = m.getName();
if (mname.startsWith("get")) {
String name = mname.substring(3, mname.length());// 截取字段
name = name.substring(0, 1).toLowerCase()
+ name.substring(1, name.length());// 把首字母变小写
String value = m.invoke(obj)==null?"":m.invoke(obj).toString();
if(cla.equals(YdOrderRelationshipInfoSyncItem.class)&&name.equals("unionId")&&(value==null||value.equals(""))){
continue;
}
map.put(name,value);// 取值
}

}
Class superclass = cla.getSuperclass();
while (!superclass.equals(Object.class)) {
Method[] superclassmethods = superclass.getDeclaredMethods();
for (Method m : superclassmethods) {
String mname = m.getName();
if (mname.startsWith("get")) {
String name = mname.substring(3, mname.length());// 截取字段
name = name.substring(0, 1).toLowerCase()
+ name.substring(1, name.length());// 把首字母变小写
String value = m.invoke(obj)==null?"":m.invoke(obj).toString();

if((cla.equals(OrderInfoSyncItem.class)||cla.equals(AccountPasswordInfoSyncItem.class)||cla.equals(YdOrderRelationshipInfoSyncItem.class))&&name.equals("operation"))
continue;

map.put(name,value);// 取值
}

}
superclass = superclass.getSuperclass();

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

return map;
}

public static CloseableHttpClient createSSLClientDefault(){

try {
//SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {
// 在JSSE中,证书信任管理器类就是实现了接口X509TrustManager的类。我们可以自己实现该接口,让它信任我们指定的证书。
// 创建SSLContext对象,并使用我们指定的信任管理器初始化
//信任所有
X509TrustManager x509mgr = new X509TrustManager() {

//  该方法检查客户端的证书,若不信任该证书则抛出异常
public void checkClientTrusted(X509Certificate[] xcs, String string) {
}
//   该方法检查服务端的证书,若不信任该证书则抛出异常
public void checkServerTrusted(X509Certificate[] xcs, String string) {
}
//  返回受信任的X509证书数组。
public X509Certificate[] getAcceptedIssuers() {
return null;
}
};
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, new TrustManager[] { x509mgr }, null);
////创建HttpsURLConnection对象,并设置其SSLSocketFactory对象
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext, SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);

//  HttpsURLConnection对象就可以正常连接HTTPS了,无论其证书是否经权威机构的验证,只要实现了接口X509TrustManager的类MyX509TrustManager信任该证书。
return HttpClients.custom().setSSLSocketFactory(sslsf).build();

} catch (KeyManagementException e) {

e.printStackTrace();

} catch (NoSuchAlgorithmException e) {

e.printStackTrace();

} catch (Exception e) {

e.printStackTrace();

}

// 创建默认的httpClient实例.
return  HttpClients.createDefault();

}

}
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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299

另外,在针对http进行升级时,在HTTPS的证书未经权威机构认证的情况下,访问HTTPS站点的两种方法,一种方法是把该证书导入到Java的TrustStore文件中,另一种是自己实现并覆盖JSSE缺省的证书信任管理器类。两种方法各有优缺点,第一种方法不会影响JSSE的安全性,但需要手工导入证书;第二种方法虽然不用手工导入证书,但需要小心使用,否则会带来一些安全隐患。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: