ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

Java 使用证书 请求 Https

2022-02-10 09:58:17  阅读:122  来源: 互联网

标签:java Java String 证书 Https new import conn


需求: 第三方接口请求需要我提供对应证书才能建立起请求,例如 Apple Pay 接口就需要有对应证书才能请求,找了 很多博客 大部分方法 不是 绕过SSL 就是 代码不全 又或者是 根本就用不了

1、在实现的过程当中,被几个博客给绕晕了。
例如 这段代码

    //CA根证书文件路径
    private String caPath = "D:\key.jks";
    //CA根证书生成密码
    private String caPassword = "123456";
    //客户端证书文件名
    private String clientCertPath = "d:\va.jks";
    //客户端证书生成密码
    private String clientCertPassword = "123456";

我一直不明白 CA证书文件是哪里生成出来的,因为我目前手上只有一个客户端证书,没有多余的文件了,后来 无意间问了一下 别人 ca根证书 和 Java的cacerts 信任库有什么区别 ,原来博客中说的 ca证书就是jdk下面的 cacerts 证书信任库,路径在 jdk安转目录下的 \jre\lib\security\cacerts, 默认密码是 changeit

客户端证书 就是 第三方给我们的证书, 不一定是 jks文件,可以是 p12、cer、csr文件等

具体代码实现

import lombok.extern.slf4j.Slf4j;
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.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContexts;
import org.junit.Test;
import org.linlinjava.litemall.core.util.HttpUtil;
import org.springframework.boot.test.context.SpringBootTest;

import javax.net.ssl.*;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.HashMap;
import java.util.Map;

/**
 * @Author Lizr
 * @Doc
 * @CreateTime 2022-01-25 下午 3:58
 **/
@Slf4j
@SpringBootTest
public class HttpTest {
    // JDK 信任库文件路径
    private String caPath = "F:\\JAVA\\jre\\lib\\security\\cacerts";
    //CA根证书生成密码
    private String caPassword = "changeit";
    //客户端证书文件路径
    private String clientCertPath = "E:\\key.p12";
    //客户端证书密码
    private String clientCertPassword = "a123456";
    private SSLSocketFactory sslFactory;


    @Test
    public void test() throws Exception {
    	// 测试执行
        HttpTest test = new HttpTest();
        test.httpsPost("https://cn-apple-pay-gateway.apple.com/paymentservices/paymentSession", "");

    }

    //https POST请求返回结果和结果码
    /**
    * @param requestUrl 请求地址
    * @param xml JSON字符串参数
    */
    public Map<String, Object> httpsPost(String requestUrl, String xml) throws Exception {
        Map<String, Object> map = new HashMap<>();
        OutputStreamWriter wr = null;
        HttpURLConnection conn = null;
        try {
            URL url = new URL(requestUrl);
            //start 这一段代码必须加在open之前,即支持ip访问的关键代码
            HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
                @Override
                public boolean verify(String s, SSLSession sslSession) {
                    return true;
                }
            });
            //end
            byte[] xmlBytes = xml.getBytes();
            conn = (HttpsURLConnection) url.openConnection();
            conn.setDoOutput(true);
            conn.setDoInput(true);
            conn.setUseCaches(false);
            conn.setInstanceFollowRedirects(true);
            conn.setRequestMethod("POST");
            //根据自己项目需求设置Content-Type
            conn.setRequestProperty("Content-Type", "application/xml;charset=UTF-8");
            conn.setRequestProperty("Content-Length", String.valueOf(xmlBytes.length));
            ((HttpsURLConnection) conn).setSSLSocketFactory(getSslFactory());
            wr = new OutputStreamWriter(conn.getOutputStream());
            wr.write(xml);
            wr.close();
            conn.connect();
            String responseBody = getResponseBodyAsString(conn);
            int responseCode = getResponseCode(conn);
            map.put("responseBody", responseBody);
            map.put("responseCode", responseCode);
            if (getResponseCode(conn) == 200) {
                System.out.println("请求成功");
            } else {
                System.out.println("请求失败");
            }
            System.out.println(responseBody);
            conn.disconnect();
        } catch (Exception e) {
            log.error("HTTPS请求出现异常,请求参数为:" + xml);
            e.printStackTrace();
            throw e;
        } finally {
            try {
                if (wr != null) {
                    wr.close();
                }
                if (conn != null) {
                    conn.disconnect();
                }
            } catch (Exception e) {

            }
        }
        return map;
    }
	// 创建一个自定义SSLSocketFactory 
    public SSLSocketFactory getSslFactory() throws Exception {
        if (sslFactory == null) {
            SSLContext sslContext = SSLContext.getInstance("SSL");
            TrustManager[] tm = {new MyX509TrustManager()};
            KeyStore trustStore = KeyStore.getInstance("JKS");
            //加载客户端证书
            FileInputStream clientInputStream = new FileInputStream(clientCertPath);
            trustStore.load(clientInputStream, clientCertPassword.toCharArray());
            KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
            kmf.init(trustStore, clientCertPassword.toCharArray());
            sslContext.init(kmf.getKeyManagers(), tm, new SecureRandom());
            sslFactory = sslContext.getSocketFactory();
        }
        return sslFactory;
    }
	// 状态码
    public int getResponseCode(HttpURLConnection connection) throws Exception {
        return connection.getResponseCode();
    }
	
    public String getResponseBodyAsString(HttpURLConnection connection) throws Exception {
        BufferedReader reader = null;
        if (connection.getResponseCode() == 200) {
            reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
        } else {
            reader = new BufferedReader(new InputStreamReader(connection.getErrorStream()));
        }
        StringBuffer buffer = new StringBuffer();
        String line = null;
        while ((line = reader.readLine()) != null) {
            buffer.append(line);
        }
        reader.close();
        return buffer.toString();
    }

    // 创建证书管理器类
    class MyX509TrustManager implements X509TrustManager {
        private X509TrustManager sunJSSEX509TrustManager;

        MyX509TrustManager() throws Exception {
            KeyStore ks = KeyStore.getInstance("JKS");
            //获取CA证书
            FileInputStream caInputStream = new FileInputStream(caPath);
            ks.load(caInputStream, caPassword.toCharArray());
            TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509", "SunJSSE");
            tmf.init(ks);
            TrustManager tms[] = tmf.getTrustManagers();
            for (int i = 0; i < tms.length; i++) {
                if (tms[i] instanceof X509TrustManager) {
                    sunJSSEX509TrustManager = (X509TrustManager) tms[i];
                    return;
                }
            }
            throw new Exception("Couldn't not initialize");
        }

        @Override
        public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
            try {
                sunJSSEX509TrustManager.checkClientTrusted(x509Certificates, s);
            } catch (Exception e) {

            }
        }

        @Override
        public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
            try {
                sunJSSEX509TrustManager.checkServerTrusted(x509Certificates, s);
            } catch (Exception e) {

            }
        }

        @Override
        public X509Certificate[] getAcceptedIssuers() {
            return sunJSSEX509TrustManager.getAcceptedIssuers();
        }

    }
}

标签:java,Java,String,证书,Https,new,import,conn
来源: https://blog.csdn.net/qq_40739917/article/details/122854267

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有