java實現 HTTP/HTTPS請求繞過證書檢測程式碼實現
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資源.
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)上面。
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();
}
}
另外,在針對http進行升級時,在HTTPS的證書未經權威機構認證的情況下,訪問HTTPS站點的兩種方法,一種方法是把該證書匯入到Java的TrustStore檔案中,另一種是自己實現並覆蓋JSSE預設的證書信任管理器類。兩種方法各有優缺點,第一種方法不會影響JSSE的安全性,但需要手工匯入證書;第二種方法雖然不用手工匯入證書,但需要小心使用,否則會帶來一些安全隱患。
相關推薦
java實現 HTTP/HTTPS請求繞過證書檢測程式碼實現
1、開發需求 需要實現在服務端發起HTTP/HTTPS請求,訪問其他程式資源。 2、URLConnection和HTTPClient的比較 HttpClient是個很不錯的開源框架,封裝了訪問http的請求頭,引數,內容體,響應等等, De
nginx學習筆記(一) 用nginx實現本地https請求轉http請求
error erro 需要 ror har file key media nginx代理 接到項目需求需要將一些https請求利用nginx代理到http接口上,因此要在本地上搭環境進行測試,現在將該過程記錄一下。 生成證書 1. 使用openssl生成密鑰privkey.
Java實現HTTP Get請求
wechat:812716131 ------------------------------------------------------ 技術交流群請聯絡上面wechat ----------------------------------------------
JAVA 實現HTTP POST請求報文格式分析
在開發中,我們使用的比較多的HTTP請求方式基本上就是GET、POST。其中GET用於從伺服器獲取資料,POST主要用於向伺服器提交一些表單資料,例如檔案上傳等。而我們在使用HTTP請求時中遇到的比較麻煩的事情就是構造檔案上傳的HTTP報文格式,這個格式雖說也比較簡單,
實現http/https的代理及證書匯入
import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.net.URI; import
java Android OKHttp HTTPS 請求證書驗證 PEM證書(1)
呼叫new CustomTrust() 即可產生OkHttpClient 關鍵點: 1、將pem證書放入Raw或者assets目錄。 2、證書的KeyStore讀取方式。 3、HostnameVerifier過濾驗證。 講解: Pem 有多個 Ce
HTTPS請求 SSL證書驗證
cer import failed blog kit urllib2 highlight www. header import urllib2 url = "https://www.12306.cn/mormhweb/" headers = {"User-Agent"
Jmeter Web 性能測試入門 (二):Fiddler 抓取 http/https 請求
功能 wrap 3-9 req safari itl box 移動 移動設備 jmeter自帶了攔截request的功能,並且也有對應的tool:badboy 可以用。但由於我經常做移動端的項目,個人還是習慣用fiddler來收集request。 官網下載並安裝Fiddle
使用谷歌瀏覽器開發者工具分析 http/https 請求耗時
web1、打開工具2、各部分的含義 參考文章:https://developers.google.com/web/tools/chrome-devtools/network-performance/reference#timing-explanation使用谷歌瀏覽器開發者工具分析 http/https 請求
關於JAVA發送Https請求(HttpsURLConnection和HttpURLConnection)
chan null true 個人 any implement 忽略 環境 區別 關於JAVA發送Https請求(HttpsURLConnection和HttpURLConnection) 【轉】 https協議對於開發者而言其實只是多了一步證書驗證的過程。這個
Python爬蟲入門之二HTTP(HTTPS)請求與響應
HTTP和HTTPS HTTP協議(HyperText Transfer Protocol,超文字傳輸協議):是一種釋出和接收 HTML頁面的方法。 HTTPS(Hypertext Transfer Protocol over Secure Socket Layer)簡單講是HTTP的安全版,在HTTP下
stm32f103zet6實現HTTP協議請求,UTF-8轉碼JSON打包上傳
概述: 最近在做一個專案,需要用stm32f103zet6開發板走HTTP協議,向疲勞駕駛檢測裝置傳送請求訊息,使其下發人臉識別的圖片或引數資訊,開發板進行接收,要求如下: 1. 開發板作為客戶端、疲勞駕駛檢測是被作為伺服器端 2. 標準HTTP協議 3. 請求方法使用PO
處理HTTPS請求 SSL證書驗證
現在隨處可見 https 開頭的網站,urllib2可以為 HTTPS 請求驗證SSL證書,就像web瀏覽器一樣,如果網站的SSL證書是經過CA認證的,則能夠正常訪問,如:https://www.baidu.com/等...如果SSL證書驗證不通過,或者作業系統不信任伺服器的安全證書,比如瀏覽器在訪
Nginx+ lua實現http轉發請求
最近要使用nginx+lua實現 一個需求: 在nginx的location部分,請求時,判斷使用者是否為會員,如果是會員,則跳轉到a頁面,否則跳轉到b頁面。 使用者服務是一個單獨
java傳送http post請求
import java.lang.reflect.Method; import java.net.HttpURLConnection; import java.util.ArrayList; import java.util.Iterator; import java.ut
weblogic傳送https請求的證書錯誤的解決辦法
問題原因:部署後,使用了Weblogic的jar包,導致報錯(誰不知道啊...)。至於哪個jar包,我真不知道了。把報錯的weblogic相關路徑往瀏覽器一貼。有如下答案http://blog.csdn.net/u014520797/article/details/50263089 。這哥們讓我配置webl
Android中進行https請求信任證書問題
前言 在Android開發專案中難免要進行https請求,如果你也遇到這樣的問題,那麼我想這片部落格能對你有些幫助。java.security.cert.CertPathValidatorException: Trust anchor for certification
Charles如何抓取http/https請求
charles ,我們親切的把它稱作茶壺,功能還是十分強大的,尤其是在mac上無法使用fiddler更是。。 其實很容易上手,下載安裝,手機設定下ip代理不久可以了嘛?但是你發現包為https的時候就不那麼容易了,所以寫一個教程,也是自己設定的過程記錄下來。順便把正常htt
C# HttpWebRequest GET HTTP HTTPS 請求
這個需求來自於我最近練手的一個專案,在專案中我需要將一些自己發表的和收藏整理的網文集中到一個地方存放,如果全部採用手工操作工作量大而且繁瑣,因此周公決定利用C#來實現。在很多地方都需要驗證使用者身份才可以進行下一步操作,這就免不了POST請求來登入,在實際過程中發現有些網
C# 實現HTTP POST請求與接收響應
用C#實現HTTP請求比較容易實現。根據網上的程式修改而成,實現程式碼如下: using System; using System.Collections.Generic; using System.ComponentModel; using System