Java調用HTTPS接口實現(xiàn)繞過SSL認證
1.說明
網絡編程中,HTTPS(Hypertext Transfer Protocol Secure)是一種通過加密的方式在計算機網絡上進行安全通信的協(xié)議。網絡傳輸協(xié)議,跟http相比更安全,因為他加上了SSL/TLS協(xié)議來加密通信內容。
Java調用HTTPS,需要與客戶端建立連接,但是建立連接的時候,需要進行SSL認證。有的時候為了方便調用,我們會繞過SSL認證。但是在特定環(huán)境中,繞過SSL認證是十分不安全的,不推薦這么做。SSL認證是確保通信安全的重要手段,繞過認證的話可能帶來一系列的安全問題。
所以一般繞過SSL認證不在生產環(huán)境中使用。
2.繞過SSL認證
因為我本次調用HTTPS接口的目的是調用數(shù)據(jù),存儲在表中,不需要跨環(huán)境,只在本地執(zhí)行,所以進行SSL認證稍有繁瑣,所以我決定繞過SSL認證。
通過自定義SSL上下文的方式,繞過SSL認證的方式。通過自定義信任管理器,你可以在繞過證書驗證的同時,實現(xiàn)自己的證書驗證邏輯。這對于使用自簽名證書或特定信任機制的情況很有用。
最后返回一個繞過SSL認證的 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 上下文和主機名驗證器應用于 HTTPS 連接 SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext, hostnameVerifier); // 創(chuàng)建自定義的 CloseableHttpClient 實例,將 SSL 連接套接字工廠應用于 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連接中不會對服務器的主機名進行驗證。主機名驗證器用于驗證SSL證書中的主機名與服務器實際的主機名是否匹配。NoopHostnameVerifier是一個空實現(xiàn)的主機名驗證器,它繞過了主機名驗證,即使主機名不匹配,也會繼續(xù)進行SSL連接。
- 創(chuàng)建一個 SSL 連接套接字工廠(SSLConnectionSocketFactory),將自定義的 SSL 上下文和主機名驗證器應用于 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法識別,將返回默認的 CloseableHttpClient 實例。
3.調用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); //設置請求體格式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請求,并從響應中提取特定的數(shù)據(jù)。
代碼中的execute方法聲明了拋出Exception異常,它接收一個String類型的參數(shù)param,但實際上沒有使用到該參數(shù)。
首先,代碼定義了服務的URL和授權頭信息。
然后,通過調用Myutils.createSSLClientDefault()方法創(chuàng)建一個自定義的SSL HttpClient對象。就是上邊繞過SSL對應的方法
接下來,創(chuàng)建一個HttpPost對象,并設置請求的URL和請求頭信息。
然后,構造請求體的JSON參數(shù),并設置到HttpPost對象中。
構造請求體的使用需要使用json格式參數(shù),也可以直接使用 GJson json = new GJson(jsonStr);將非JSON數(shù)據(jù)轉化為JSON格式,JSON格式的S他臉紅,需要給每個參數(shù)加上引號,并且使用\轉譯。所以setEntity的時候需要帶有JSON格式的字符串。
String jsonStr = "{\"name\":\"John\",\"age\":30,\"city\":\"New York\"}"; GJson json = new GJson(jsonStr);
接著,通過調用HttpClient的execute方法發(fā)送HttpPost請求,并接收HttpResponse響應。
將響應的實體內容轉換為字符串,并存儲在result變量中。
使用Jackson庫的ObjectMapper類解析result字符串為JsonNode對象。
從JsonNode對象中獲取特定的數(shù)據(jù),例如從"data"鍵中獲取"encData"鍵的值。
最后,將獲取到的"encData"值存儲在encDate2變量中。
我的出參是這樣的,所以按照自己的格式替換數(shù)據(jù),便可以得到你想要的出參
{ "code": "0", "message": "success", "data": { "encData": { "date": "wxpOGSdQD68Jp7fC4KV" } } }
需要注意的是,代碼中的URL、授權頭信息、JSON參數(shù)等是示例數(shù)據(jù),你需要根據(jù)實際情況進行修改和替換。
此代碼片段只是一個簡單的示例,實際使用時應該考慮異常處理、資源釋放等更完善的邏輯。
以上就是Java調用HTTPS接口實現(xiàn)繞過SSL認證的詳細內容,更多關于Java HTTPS接口的資料請關注腳本之家其它相關文章!
相關文章
JAVA開發(fā)常用類庫UUID、Optional、ThreadLocal、TimerTask、Base64使用方法與實例詳
這篇文章主要介紹了JAVA開發(fā)常用類庫UUID、Optional、ThreadLocal、TimerTask、Base64使用方法與實例詳解,需要的朋友可以參考下2020-02-02springboot整合apache ftpserver詳細教程(推薦)
這篇文章主要介紹了springboot整合apache ftpserver詳細教程,本文給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下2020-01-01SpringBoot使用Caffeine實現(xiàn)緩存的示例代碼
本文主要介紹了SpringBoot使用Caffeine實現(xiàn)緩存的示例代碼,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2022-07-07一種新的日期處理方式之JavaScript Temporal API
JavaScript Temporal API是一種為Web開發(fā)人員提供了一種新的處理日期和時間數(shù)據(jù)類型的方式。它的目的是使操作日期和時間更加簡單和可靠,而且不用擔心歷史時區(qū)問題或全球化協(xié)調時間(UTC)之類的問題,感興趣的同學可以參考閱讀2023-05-05