Java調(diào)用HTTPS接口實現(xiàn)繞過SSL認(rèn)證
1.說明
網(wǎng)絡(luò)編程中,HTTPS(Hypertext Transfer Protocol Secure)是一種通過加密的方式在計算機網(wǎng)絡(luò)上進行安全通信的協(xié)議。網(wǎng)絡(luò)傳輸協(xié)議,跟http相比更安全,因為他加上了SSL/TLS協(xié)議來加密通信內(nèi)容。
Java調(diào)用HTTPS,需要與客戶端建立連接,但是建立連接的時候,需要進行SSL認(rèn)證。有的時候為了方便調(diào)用,我們會繞過SSL認(rèn)證。但是在特定環(huán)境中,繞過SSL認(rèn)證是十分不安全的,不推薦這么做。SSL認(rèn)證是確保通信安全的重要手段,繞過認(rèn)證的話可能帶來一系列的安全問題。
所以一般繞過SSL認(rèn)證不在生產(chǎn)環(huán)境中使用。
2.繞過SSL認(rèn)證
因為我本次調(diào)用HTTPS接口的目的是調(diào)用數(shù)據(jù),存儲在表中,不需要跨環(huán)境,只在本地執(zhí)行,所以進行SSL認(rèn)證稍有繁瑣,所以我決定繞過SSL認(rèn)證。
通過自定義SSL上下文的方式,繞過SSL認(rèn)證的方式。通過自定義信任管理器,你可以在繞過證書驗證的同時,實現(xiàn)自己的證書驗證邏輯。這對于使用自簽名證書或特定信任機制的情況很有用。
最后返回一個繞過SSL認(rèn)證的 HttpClient對象。
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContextBuilder;
// 創(chuàng)建自定義的 SSL 上下文,用于繞過證書驗證
public static CloseableHttpClient createSSLClientDefault() {
try {
SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {
// 信任所有證書
public boolean isTrusted(X509Certificate[] arg0, String arg1)
throws CertificateException {
return true;
}
}).build();
// 創(chuàng)建主機名驗證器,用于繞過主機名驗證
HostnameVerifier hostnameVerifier = NoopHostnameVerifier.INSTANCE;
// 創(chuàng)建 SSL 連接套接字工廠,將自定義的 SSL 上下文和主機名驗證器應(yīng)用于 HTTPS 連接
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext, hostnameVerifier);
// 創(chuàng)建自定義的 CloseableHttpClient 實例,將 SSL 連接套接字工廠應(yīng)用于 HTTP 客戶端
return HttpClients.custom().setSSLSocketFactory(sslsf).build();
} catch (KeyManagementException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (KeyStoreException e) {
e.printStackTrace();
}
return HttpClients.createDefault();
}該方法的實現(xiàn)邏輯如下:
- 創(chuàng)建一個自定義的 SSL 上下文(SSLContext),用于繞過 SSL 證書驗證。
- 在 SSL 上下文中加載信任材料(TrustMaterial),并使用自定義的 TrustStrategy 來信任所有證書。
- 創(chuàng)建一個主機名驗證器(HostnameVerifier),用于繞過主機名驗證。使用NoopHostnameVerifier(主機名驗證器)意味著在SSL連接中不會對服務(wù)器的主機名進行驗證。主機名驗證器用于驗證SSL證書中的主機名與服務(wù)器實際的主機名是否匹配。NoopHostnameVerifier是一個空實現(xiàn)的主機名驗證器,它繞過了主機名驗證,即使主機名不匹配,也會繼續(xù)進行SSL連接。
- 創(chuàng)建一個 SSL 連接套接字工廠(SSLConnectionSocketFactory),將自定義的 SSL 上下文和主機名驗證器應(yīng)用于 HTTPS 連接。創(chuàng)建自定義的SSL連接。有四種實現(xiàn)方式(指定SSL/TLS協(xié)議版本、指定加密算法和密碼套件、自定義信任管理器、自定義主機名驗證器),其中通過SSLConnectionSocketFactory指定自定義的主機名驗證器(HostnameVerifier),以控制主機名驗證的行為。
- 創(chuàng)建一個自定義的 CloseableHttpClient 實例,使用上述的 SSL 連接套接字工廠。
- 如果在創(chuàng)建 SSL 上下文時發(fā)生異常,將打印異常堆棧跟蹤信息。
- 如果在創(chuàng)建 SSL 上下文時發(fā)生異?;驋伋龅漠惓n愋蜔o法識別,將返回默認(rèn)的 CloseableHttpClient 實例。
3.調(diào)用HTTPS接口
private static final String SERVICE_URL = "https://ip:port/api/v1/cipher/json/create";
private static final String AUTHORIZATION_HEADER = "savhsdkfas==";
public ReturnT<String> execute(String param) throws Exception {
//發(fā)送httpPost請求
//創(chuàng)建HttpClient
HttpClient httpclient = Myutils.createSSLClientDefault();
//發(fā)送接口地址
HttpPost httppost = new HttpPost(SERVICE_URL);
//設(shè)置請求體格式Content-Type
httppost.setHeader("Content-Type", "application/json");
httppost.setHeader("Authorization", AUTHORIZATION_HEADER);
//定義String請求Json參數(shù)體
httppost.setEntity(new StringEntity(new String("{" +
"\"keyCode\": \"" + keycode + "\"," +
"\"algorithmParam\": \"SM4/ECB/PKCS7Padding\"," +
"\"data\": {" +
"\"SetlNewDTO\": \"" + this.convertDtoToBase64(accountPayDO) + "\"" +
"}" +
"}"), Charset.forName("UTF-8")));
//發(fā)送請求并接收response
HttpResponse httpresponse = httpclient.execute(httppost);
String result = EntityUtils.toString(httpresponse.getEntity(), "UTF-8");
ObjectMapper objectMapper = new ObjectMapper();
JsonNode responseJson = objectMapper.readTree(result);
// 從JSON對象中獲取鍵值對,根據(jù)出參格式獲取出參數(shù)據(jù)
JsonNode jsonNode = responseJson.get("data");
JsonNode encData1 = jsonNode.get("encData");
String encDate2 = encData1.toString();
}這段代碼是一個使用Apache HttpClient庫發(fā)送HTTP POST請求的示例。它發(fā)送一個帶有JSON參數(shù)的POST請求,并從響應(yīng)中提取特定的數(shù)據(jù)。
代碼中的execute方法聲明了拋出Exception異常,它接收一個String類型的參數(shù)param,但實際上沒有使用到該參數(shù)。
首先,代碼定義了服務(wù)的URL和授權(quán)頭信息。
然后,通過調(diào)用Myutils.createSSLClientDefault()方法創(chuàng)建一個自定義的SSL HttpClient對象。就是上邊繞過SSL對應(yīng)的方法
接下來,創(chuàng)建一個HttpPost對象,并設(shè)置請求的URL和請求頭信息。
然后,構(gòu)造請求體的JSON參數(shù),并設(shè)置到HttpPost對象中。
構(gòu)造請求體的使用需要使用json格式參數(shù),也可以直接使用 GJson json = new GJson(jsonStr);將非JSON數(shù)據(jù)轉(zhuǎn)化為JSON格式,JSON格式的S他臉紅,需要給每個參數(shù)加上引號,并且使用\轉(zhuǎn)譯。所以setEntity的時候需要帶有JSON格式的字符串。
String jsonStr = "{\"name\":\"John\",\"age\":30,\"city\":\"New York\"}";
GJson json = new GJson(jsonStr);
接著,通過調(diào)用HttpClient的execute方法發(fā)送HttpPost請求,并接收HttpResponse響應(yīng)。
將響應(yīng)的實體內(nèi)容轉(zhuǎn)換為字符串,并存儲在result變量中。
使用Jackson庫的ObjectMapper類解析result字符串為JsonNode對象。
從JsonNode對象中獲取特定的數(shù)據(jù),例如從"data"鍵中獲取"encData"鍵的值。
最后,將獲取到的"encData"值存儲在encDate2變量中。
我的出參是這樣的,所以按照自己的格式替換數(shù)據(jù),便可以得到你想要的出參
{
"code": "0",
"message": "success",
"data": {
"encData": {
"date": "wxpOGSdQD68Jp7fC4KV"
}
}
}
需要注意的是,代碼中的URL、授權(quán)頭信息、JSON參數(shù)等是示例數(shù)據(jù),你需要根據(jù)實際情況進行修改和替換。
此代碼片段只是一個簡單的示例,實際使用時應(yīng)該考慮異常處理、資源釋放等更完善的邏輯。
以上就是Java調(diào)用HTTPS接口實現(xiàn)繞過SSL認(rèn)證的詳細(xì)內(nèi)容,更多關(guān)于Java HTTPS接口的資料請關(guān)注腳本之家其它相關(guān)文章!
- Java如何基于okhttp請求SSE接口流式返回詳解
- Java請求Http接口OkHttp超詳細(xì)講解(附帶工具類)
- java+Okhttp3調(diào)用接口的實例
- Java中的HttpServletRequest接口詳細(xì)解讀
- Java調(diào)用第三方http接口的四種方式總結(jié)
- Java發(fā)送http請求調(diào)用第三方接口獲取token方式
- Java調(diào)用第三方http接口的常用方式總結(jié)
- Java實現(xiàn)調(diào)用對方http接口得到返回數(shù)據(jù)
- Java 調(diào)用 HTTP 接口的 7 種方式示例代碼(全網(wǎng)最全指南)
相關(guān)文章
Java雜談之類和對象 封裝 構(gòu)造方法以及代碼塊詳解
在現(xiàn)實世界中,真實存在的東西,比如吉普車,卡丁車,貨車。我們在認(rèn)識它的時候就會在腦海中將它抽象為一種類別叫做車。 好了,那再計算機世界中,它同樣的也會這樣做2021-09-09
使用kotlin集成springboot開發(fā)的超詳細(xì)教程
目前大多數(shù)都在使用java集成 springboot進行開發(fā),本文演示僅僅將 java換成 kotlin,其他不變的情況下進行開發(fā),需要的朋友可以參考下2021-09-09
圖解Spring Security 中用戶是如何實現(xiàn)登錄的
這篇文章主要介紹了圖解Spring Security 中用戶是如何實現(xiàn)登錄的,文中通過示例代碼和圖片介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-07-07
SpringBoot任意版本集成Swagger各種版本的操作指南
在學(xué)習(xí)Swagger生成API文檔的時候經(jīng)常會遇到問題,而目前市面上大部分技術(shù)分享者的SpringBoot版本并沒和我們的同步,導(dǎo)致一些一模一樣的代碼,在我們的項目上卻無法使用,這是一個經(jīng)常性的問題,本文章就旨在和大家搞定SpringBoot任意版本集成Swagger各種版本2024-07-07
Spring遠(yuǎn)程調(diào)用HttpClient/RestTemplate的方法
這篇文章主要介紹了Spring遠(yuǎn)程調(diào)用HttpClient/RestTemplate的方法,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-03-03
Java?C++題解leetcode消失的兩個數(shù)字實例
這篇文章主要介紹了Java?C++題解leetcode消失的兩個數(shù)字實例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-09-09
Java設(shè)計模式之責(zé)任鏈模式的概念、實現(xiàn)以及netty中的責(zé)任鏈模式
這篇文章主要給大家介紹了關(guān)于設(shè)計模式之責(zé)任鏈模式的概念、實現(xiàn)以及netty中的責(zé)任鏈模式的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-12-12

