• 基于springboot 根据ca.crt、client.crt和client.key文件实现与服务端https通讯


    基于springboot 根据ca.crt、client.crt和client.key文件实现与服务端https通讯
    服务端提供了三个文件需要进行TLS方式通讯,三个文件分别为ca.crt、client.crt、client.key:
    ca.crt 为服务端证书
    client.crt 为服务端分配给客户端的证书
    client.key 为服务端分配给客户端证书私钥

    三个文件的具体格式说明我就不做赘述了,都可以在网上查到,也不多说废话,直接贴代码:

    参考文章
    参考文章: https://blog.csdn.net/qq_38417913/article/details/82150186.

    pom.xml添加依赖
    // pom.xml 添加依赖
    <dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId>
    <version>4.5.6</version>
    </dependency>

    1
    2
    3
    4
    5
    6
    7
    客户端认证代码
    // An highlighted block


    import com.alibaba.fastjson.JSONObject;
    import com.Exception.base.exceptions.BusinessException;
    import org.apache.http.HttpEntity;
    import org.apache.http.client.config.RequestConfig;
    import org.apache.http.client.methods.CloseableHttpResponse;
    import org.apache.http.client.methods.HttpPost;
    import org.apache.http.conn.ssl.NoopHostnameVerifier;
    import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
    import org.apache.http.entity.StringEntity;
    import org.apache.http.impl.client.CloseableHttpClient;
    import org.apache.http.impl.client.HttpClients;
    import org.apache.logging.log4j.LogManager;
    import org.apache.logging.log4j.Logger;
    import org.springframework.stereotype.Component;
    import org.springframework.util.StreamUtils;
    import sun.misc.BASE64Decoder;

    import javax.net.ssl.KeyManagerFactory;
    import javax.net.ssl.SSLContext;
    import javax.net.ssl.TrustManagerFactory;
    import java.io.*;
    import java.nio.charset.StandardCharsets;
    import java.security.KeyFactory;
    import java.security.KeyStore;
    import java.security.PrivateKey;
    import java.security.SecureRandom;
    import java.security.cert.CertificateFactory;
    import java.security.cert.X509Certificate;
    import java.security.spec.PKCS8EncodedKeySpec;


    /**
    * @ClassName CertificateHttpsTools
    * @Description 客户端带证书https方式请求服务端
    * @Author user
    * @Date 2020/6/18 10:23
    * @Version 1.0
    **/
    @Component
    public class CertificateHttpsTools {
    private static Logger logger = LogManager.getLogger(CertificateHttpsTools.class);


    public static final String CA_PATH = "C:/Users/Desktop/cer/ca.crt";
    public static final String CRT_PATH = "C:/Users/Desktop/cer/client.crt";
    public static final String KEY_PATH = "C:/Users/Desktop/cer/client.key";
    public static final String PASSWORD = "123";

    public static String httpPost(String url, String jsonParam) throws IOException {
    CloseableHttpClient httpClient = null;

    String result = null;
    logger.info("请求数据:"+jsonParam);

    try{
    //加载证书
    SSLConnectionSocketFactory sslsf = getSSLSocktetBidirectional();
    //设置认证信息到httpclient
    httpClient = HttpClients.custom().setSSLSocketFactory(sslsf).build();

    }catch (Exception e){
    logger.error("证书读取失败");
    e.printStackTrace();
    throw new BusinessException("证书读取失败");


    }

    // 根据默认超时限制初始化requestConfig
    RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(25000).setConnectTimeout(25000).build();

    //post通讯初始化
    HttpPost httpPost = new HttpPost(url);

    // 设置报文头 得指明使用UTF-8编码,否则到API服务器XML的中文不能被成功识别
    httpPost.addHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");

    //添加请求报文体
    StringEntity reqentity = new StringEntity(jsonParam, "UTF-8");
    httpPost.setEntity(reqentity);

    // 设置请求器的配置
    httpPost.setConfig(requestConfig);


    try {
    CloseableHttpResponse response = null;
    InputStream reqin = null;
    try {

    //打印请求报文体
    reqin = httpPost.getEntity().getContent();
    String reqBbody = StreamUtils.copyToString(reqin, StandardCharsets.UTF_8);
    logger.info("请求数据:"+reqBbody);

    //与服务端通讯
    response = httpClient.execute(httpPost);

    //打印通讯状态
    logger.info(JSONObject.toJSONString(response.getStatusLine()));

    HttpEntity entity = response.getEntity();
    InputStream in = null;
    try {

    in = entity.getContent();
    String rspBbody = StreamUtils.copyToString(in, StandardCharsets.UTF_8);
    logger.info("应答为:"+rspBbody);
    in.close();

    result = rspBbody;

    // result = EntityUtils.toString(entity, "UTF-8");


    } catch (IOException e) {
    logger.error("服务端应答信息读取失败");
    e.printStackTrace();
    throw new BusinessException("服务端应答信息读取失败");
    }finally {
    if (in !=null){
    in.close();
    }
    }

    } catch (IOException e) {
    logger.error("与服务端通讯失败");
    e.printStackTrace();
    throw new BusinessException("与服务端通讯失败");
    }finally {
    try{
    //释放资源
    if (httpClient != null){
    httpClient.close();
    }

    if (response != null){
    response.close();
    }
    if (reqin != null){
    reqin.close();
    }
    }catch (IOException e) {
    e.printStackTrace();
    }
    }


    } finally {

    httpPost.abort();

    }
    return result;

    }

    public static SSLConnectionSocketFactory getSSLSocktetBidirectional() throws Exception {
    SSLConnectionSocketFactory sslsf = null;

    try{
    // CA certificate is used to authenticate server
    CertificateFactory cAf = CertificateFactory.getInstance("X.509");
    FileInputStream caIn = new FileInputStream(CA_PATH);
    X509Certificate ca = (X509Certificate) cAf.generateCertificate(caIn);

    KeyStore caKs = KeyStore.getInstance("JKS");
    caKs.load(null, null);
    caKs.setCertificateEntry("ca-certificate", ca);
    TrustManagerFactory tmf = TrustManagerFactory.getInstance("PKIX");
    tmf.init(caKs);

    // client key and certificates are sent to server so it can authenticate us
    CertificateFactory cf = CertificateFactory.getInstance("X.509");
    FileInputStream crtIn = new FileInputStream(CRT_PATH);
    X509Certificate caCert = (X509Certificate) cf.generateCertificate(crtIn);
    crtIn.close();


    KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
    ks.load(null, null);
    ks.setCertificateEntry("certificate", caCert);
    ks.setKeyEntry("private-key", getPrivateKey( KEY_PATH), PASSWORD.toCharArray(), new java.security.cert.Certificate[] { caCert });
    KeyManagerFactory kmf = KeyManagerFactory.getInstance("PKIX");
    kmf.init(ks, PASSWORD.toCharArray());

    // finally, create SSL socket factory
    SSLContext context = SSLContext.getInstance("TLSv1.2");
    context.init(kmf.getKeyManagers(), tmf.getTrustManagers(), new SecureRandom());

    sslsf =
    new SSLConnectionSocketFactory(context,null, null,
    NoopHostnameVerifier.INSTANCE);
    }catch (Exception e){
    logger.error("证书加载失败");
    e.printStackTrace();
    throw new BusinessException("证书加载失败");
    }

    return sslsf;
    }


    private static PrivateKey getPrivateKey(String path) throws Exception {
    //byte[] buffer = Base64.getDecoder().decode(getPem(path));
    // Base64 base64 = new Base64();
    BASE64Decoder decoder = new BASE64Decoder();
    byte[] buffer = decoder.decodeBuffer(getPem(path));

    PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(buffer);
    KeyFactory keyFactory = KeyFactory.getInstance("EC");
    return keyFactory.generatePrivate(keySpec);

    }


    private static String getPem(String path) throws Exception {
    FileInputStream fin = new FileInputStream(path);
    BufferedReader br = new BufferedReader(new InputStreamReader(fin));
    String readLine = null;
    StringBuilder sb = new StringBuilder();
    while ((readLine = br.readLine()) != null) {
    if (readLine.charAt(0) == '-') {
    continue;
    } else {
    sb.append(readLine);
    sb.append('\r');
    }
    }
    fin.close();
    return sb.toString();
    }
    }



    以上代码亲测有效,如果不对之处请各位大神指正,当然有更好的方法也请各位提出来
    ————————————————
    版权声明:本文为CSDN博主「学习是不可能停的」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/jan135450/article/details/106837077/

  • 相关阅读:
    004 使用文本编辑器
    003 第一个Python程序
    002 Python解释器
    001 安装Python
    000 Python教程
    001 Java环境变量配置
    002 基础语法1
    003 基础语法2
    dede首页调用会员积分和头像代码
    DEDE 会员调用方法
  • 原文地址:https://www.cnblogs.com/telwanggs/p/16561913.html
Copyright © 2020-2023  润新知