Java调用HTTPS接口,绕过SSL认证-CSDN博客

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

1说明

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

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

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

2绕过SSL认证

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

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

最后返回一个绕过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;


// 创建自定义的 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();
			// 创建主机名验证器用于绕过主机名验证
			HostnameVerifier hostnameVerifier = NoopHostnameVerifier.INSTANCE;
			// 创建 SSL 连接套接字工厂将自定义的 SSL 上下文和主机名验证器应用于 HTTPS 连接
			SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext, hostnameVerifier);
			// 创建自定义的 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();
	}

该方法的实现逻辑如下

  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接口

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 {

        //发送httpPost请求
        //创建HttpClient
        HttpClient httpclient = Myutils.createSSLClientDefault();
        //发送接口地址
        HttpPost httppost = new HttpPost(SERVICE_URL);
        //设置请求体格式Content-Type
        httppost.setHeader("Content-Type", "application/json");
        httppost.setHeader("Authorization", AUTHORIZATION_HEADER);

        //定义String请求Json参数体
        httppost.setEntity(new StringEntity(new String("{" +
                "\"keyCode\": \"" + keycode + "\"," +
                "\"algorithmParam\": \"SM4/ECB/PKCS7Padding\"," +
                "\"data\": {" +
                "\"SetlNewDTO\": \"" + this.convertDtoToBase64(accountPayDO) + "\"" +
                "}" +
                "}"), Charset.forName("UTF-8")));
        //发送请求并接收response
        HttpResponse httpresponse = httpclient.execute(httppost);
        String result = EntityUtils.toString(httpresponse.getEntity(), "UTF-8");

        ObjectMapper objectMapper = new ObjectMapper();
        JsonNode responseJson = objectMapper.readTree(result);
        // 从JSON对象中获取键值对,根据出参格式获取出参数据
        JsonNode jsonNode = responseJson.get("data");
        JsonNode encData1 = jsonNode.get("encData");
        String encDate2 = encData1.toString();

    }

这段代码是一个使用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格式的字符串。

String jsonStr = "{\"name\":\"John\",\"age\":30,\"city\":\"New York\"}";

GJson json = new GJson(jsonStr);

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

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

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

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

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

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

{
	"code": "0",
	"message": "success",
	"data": {
		"encData": {
			"date": "wxpOGSdQD68Jp7fC4KV"
		}
	}
}

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

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

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

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6
标签: Java