• Java调用HTTPS接口,绕过SSL认证


    一.Java调用HTTPS接口,绕过SSL认证

    1:说明

    网络编程中,HTTPS(Hypertext Transfer Protocol Secure)是一种通过加密的方式在计算机网络上进行安全通信的协议。网络传输协议,跟http相比更安全,因为他加上了SSL/TLS协议来加密通信内容。

    Java调用HTTPS,需要与客户端建立连接,但是建立连接的时候,需要进行SSL认证。有的时候为了方便调用,我们会绕过SSL认证。但是在特定环境中,绕过SSL认证是十分不安全的,不推荐这么做。SSL认证是确保通信安全的重要手段,绕过认证的话可能带来一系列的安全问题。

    所以一般绕过SSL认证不在生产环境中使用。

    2:绕过SSL认证

    因为我本次调用HTTPS接口的目的是调用数据,存储在表中,不需要跨环境,只在本地执行,所以进行SSL认证稍有繁琐,所以我决定绕过SSL认证。

    通过自定义SSL上下文的方式,绕过SSL认证的方式。通过自定义信任管理器,你可以在绕过证书验证的同时,实现自己的证书验证逻辑。这对于使用自签名证书或特定信任机制的情况很有用。

    最后返回一个绕过SSL认证的 HttpClient对象。

    1. import java.security.KeyManagementException;
    2. import java.security.KeyStoreException;
    3. import java.security.NoSuchAlgorithmException;
    4. import java.security.cert.CertificateException;
    5. import java.security.cert.X509Certificate;
    6. import javax.net.ssl.HostnameVerifier;
    7. import javax.net.ssl.SSLContext;
    8. import org.apache.http.conn.ssl.NoopHostnameVerifier;
    9. import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
    10. import org.apache.http.conn.ssl.TrustStrategy;
    11. import org.apache.http.impl.client.CloseableHttpClient;
    12. import org.apache.http.impl.client.HttpClients;
    13. import org.apache.http.ssl.SSLContextBuilder;
    14. // 创建自定义的 SSL 上下文,用于绕过证书验证
    15. public static CloseableHttpClient createSSLClientDefault() {
    16. try {
    17. SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {
    18. // 信任所有证书
    19. public boolean isTrusted(X509Certificate[] arg0, String arg1)
    20. throws CertificateException {
    21. return true;
    22. }
    23. }).build();
    24. // 创建主机名验证器,用于绕过主机名验证
    25. HostnameVerifier hostnameVerifier = NoopHostnameVerifier.INSTANCE;
    26. // 创建 SSL 连接套接字工厂,将自定义的 SSL 上下文和主机名验证器应用于 HTTPS 连接
    27. SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext, hostnameVerifier);
    28. // 创建自定义的 CloseableHttpClient 实例,将 SSL 连接套接字工厂应用于 HTTP 客户端
    29. return HttpClients.custom().setSSLSocketFactory(sslsf).build();
    30. } catch (KeyManagementException e) {
    31. e.printStackTrace();
    32. } catch (NoSuchAlgorithmException e) {
    33. e.printStackTrace();
    34. } catch (KeyStoreException e) {
    35. e.printStackTrace();
    36. }
    37. return HttpClients.createDefault();
    38. }

    该方法的实现逻辑如下:

    1. 创建一个自定义的 SSL 上下文(SSLContext),用于绕过 SSL 证书验证。
    2. 在 SSL 上下文中加载信任材料(TrustMaterial),并使用自定义的 TrustStrategy 来信任所有证书。
    3. 创建一个主机名验证器(HostnameVerifier),用于绕过主机名验证。使用NoopHostnameVerifier(主机名验证器)意味着在SSL连接中不会对服务器的主机名进行验证。主机名验证器用于验证SSL证书中的主机名与服务器实际的主机名是否匹配。NoopHostnameVerifier是一个空实现的主机名验证器,它绕过了主机名验证,即使主机名不匹配,也会继续进行SSL连接。
    4. 创建一个 SSL 连接套接字工厂(SSLConnectionSocketFactory),将自定义的 SSL 上下文和主机名验证器应用于 HTTPS 连接。创建自定义的SSL连接。有四种实现方式(指定SSL/TLS协议版本、指定加密算法和密码套件、自定义信任管理器、自定义主机名验证器),其中通过SSLConnectionSocketFactory指定自定义的主机名验证器(HostnameVerifier),以控制主机名验证的行为。
    5. 创建一个自定义的 CloseableHttpClient 实例,使用上述的 SSL 连接套接字工厂。
    6. 如果在创建 SSL 上下文时发生异常,将打印异常堆栈跟踪信息。
    7. 如果在创建 SSL 上下文时发生异常或抛出的异常类型无法识别,将返回默认的 CloseableHttpClient 实例。

    3:调用HTTPS接口

    1. private static final String SERVICE_URL = "https://ip:port/api/v1/cipher/json/create";
    2. private static final String AUTHORIZATION_HEADER = "savhsdkfas==";
    3. public ReturnT execute(String param) throws Exception {
    4. //发送httpPost请求
    5. //创建HttpClient
    6. HttpClient httpclient = Myutils.createSSLClientDefault();
    7. //发送接口地址
    8. HttpPost httppost = new HttpPost(SERVICE_URL);
    9. //设置请求体格式Content-Type
    10. httppost.setHeader("Content-Type", "application/json");
    11. httppost.setHeader("Authorization", AUTHORIZATION_HEADER);
    12. //定义String请求Json参数体
    13. httppost.setEntity(new StringEntity(new String("{" +
    14. "\"keyCode\": \"" + keycode + "\"," +
    15. "\"algorithmParam\": \"SM4/ECB/PKCS7Padding\"," +
    16. "\"data\": {" +
    17. "\"SetlNewDTO\": \"" + this.convertDtoToBase64(accountPayDO) + "\"" +
    18. "}" +
    19. "}"), Charset.forName("UTF-8")));
    20. //发送请求并接收response
    21. HttpResponse httpresponse = httpclient.execute(httppost);
    22. String result = EntityUtils.toString(httpresponse.getEntity(), "UTF-8");
    23. ObjectMapper objectMapper = new ObjectMapper();
    24. JsonNode responseJson = objectMapper.readTree(result);
    25. // 从JSON对象中获取键值对,根据出参格式获取出参数据
    26. JsonNode jsonNode = responseJson.get("data");
    27. JsonNode encData1 = jsonNode.get("encData");
    28. String encDate2 = encData1.toString();
    29. }

    这段代码是一个使用Apache HttpClient库发送HTTP POST请求的示例。它发送一个带有JSON参数的POST请求,并从响应中提取特定的数据。

    代码中的execute方法声明了抛出Exception异常,它接收一个String类型的参数param,但实际上没有使用到该参数。

    首先,代码定义了服务的URL和授权头信息。

    然后,通过调用Myutils.createSSLClientDefault()方法创建一个自定义的SSL HttpClient对象。就是上边绕过SSL对应的方法

    接下来,创建一个HttpPost对象,并设置请求的URL和请求头信息。

    然后,构造请求体的JSON参数,并设置到HttpPost对象中。

    构造请求体的使用需要使用json格式参数,也可以直接使用 GJson json = new GJson(jsonStr);将非JSON数据转化为JSON格式,JSON格式的S他脸红,需要给每个参数加上引号,并且使用\转译。所以setEntity的时候需要带有JSON格式的字符串。

    1. String jsonStr = "{\"name\":\"John\",\"age\":30,\"city\":\"New York\"}";
    2. GJson json = new GJson(jsonStr);

    接着,通过调用HttpClient的execute方法发送HttpPost请求,并接收HttpResponse响应。

    将响应的实体内容转换为字符串,并存储在result变量中。

    使用Jackson库的ObjectMapper类解析result字符串为JsonNode对象。

    从JsonNode对象中获取特定的数据,例如从"data"键中获取"encData"键的值。

    最后,将获取到的"encData"值存储在encDate2变量中。

    我的出参是这样的,所以按照自己的格式替换数据,便可以得到你想要的出参

    1. {
    2. "code": "0",
    3. "message": "success",
    4. "data": {
    5. "encData": {
    6. "date": "wxpOGSdQD68Jp7fC4KV"
    7. }
    8. }
    9. }

    需要注意的是,代码中的URL、授权头信息、JSON参数等是示例数据,你需要根据实际情况进行修改和替换。

    此代码片段只是一个简单的示例,实际使用时应该考虑异常处理、资源释放等更完善的逻辑。

     最高级的自律,从一点点到亿点点。

    二. Java直接调用HTTP接口,并且获取List出参,输出数据List

    1.代码实现 

    1. public WrapperResponse> queryBigWarning(WarnInfoBInfoQueryDTO warnInfoBInfoQueryDTO) throws Exception {
    2. String SERVICE_URL = "http://127.0.0.1:8889/wakljfa";
    3. //发送httpPost请求
    4. //创建HttpClient
    5. HttpClient httpclient = HttpClients.createDefault();
    6. //发送接口地址
    7. HttpPost httppost = new HttpPost(SERVICE_URL);
    8. //定义String请求Json参数体
    9. httppost.setEntity(new StringEntity(new String("{" +
    10. "\"pageNum\": \"" + warnInfoBInfoQueryDTO.getPageNum() + "\"," +
    11. "\"pageSize\": \"" + warnInfoBInfoQueryDTO.getPageSize() + "\"," +
    12. "\"warnType\": \"" + warnInfoBInfoQueryDTO.getWarnType() + "\"" +
    13. "}"), Charset.forName("UTF-8")));
    14. httppost.setHeader("Content-Type", "application/json");
    15. //发送请求并接收response
    16. HttpResponse httpresponse = httpclient.execute(httppost);
    17. String result = EntityUtils.toString(httpresponse.getEntity(), "UTF-8");
    18. ObjectMapper objectMapper = new ObjectMapper();
    19. JsonNode responseJson = objectMapper.readTree(result);
    20. // 从JSON对象中获取键值对,根据出参格式获取出参数据
    21. JsonNode data = responseJson.get("data");
    22. JsonNode listWarn = pageInfo.get("list");
    23. Iterator iterator = listWarn.iterator();
    24. List warningDTOS = new ArrayList<>();
    25. while (iterator.hasNext()) {
    26. WarningDTO warningDTO = new WarningDTO();
    27. JsonNode warningNode = iterator.next();
    28. String warnOcurTime= warningNode.get("warnOcurTime").asText();
    29. warningDTO.setWarnOcurTime(warnOcurTime);
    30. String warnId= warningNode.get("warnId").asText();
    31. warningDTO.setWarnId( warnId);
    32. String id= warningNode.get("id").asText();
    33. warningDTO.setId( Id);
    34. warningDTOS.add(warningDTO);
    35. }
    36. return WrapperResponse.success(warningDTOS);
    37. }

    2.出参模式

    1. "data": {
    2. "list": [
    3. {
    4. "warnId": "000000000000000000000000000201",
    5. "warnOcurTime": 1672502400000,
    6. "id": "000000000000000000000000000201"
    7. },
    8. {
    9. "warnId": "000000000000000000000000000301",
    10. "warnOcurTime": 1672502400000,
    11. "id": "000000000000000000000000000301"
    12. }
    13. ]
    14. }

    (•̀ᴗ• ) ̑̑  看到这的朋友。如果可以的话。点点下边的链接帮我投上两票哦。๐•ᴗ•๐✧๐•ᴗ•๐✧(•‿•)

    掘金2023年度人气创作者打榜中,快来帮我打榜吧~

  • 相关阅读:
    vue3+ts+elementplus 进度条制作浏览器进度条
    【图像分类损失】PolyLoss:一个优于 Cross-entropy loss和Focal loss的分类损失
    【Nginx】彻底卸载Nginx以及安装Nginx的详细教程
    Spring~五种存储Bean对象的类注解、方法注解(@Bean)以及Bean对象的获取
    leetcode237 删除链表中的节点
    面试算法6:排序数组中的两个数字之和
    Unity中使用Xlua调用lua相关
    jenkins+sonar
    多态概述、多态中成员变量的访问原则、引用数据类型的向上向下转型、多态的应用、包和访问权限
    ChatGPT的工作原理是什么?
  • 原文地址:https://blog.csdn.net/qq_45656077/article/details/134153471