自建CA证书,java实现通过OkHttpClient发送https(验证ca证书)请求

1、实现步骤

1.1 环境准备

image.png

image.png

<!-- 将客户端公钥导入的服务端jdk信任库 -->
keytool -import -alias sslTestClient_01 -file F:\ghj\prooooject\jar\test\client\sslTestClient_01.cer -keystore 'C:\Program Files\Java\jdk1.8.0_261\jre\lib\security\cacerts' -storepass changeit –v

<!-- 将服务端公钥导入到客户端的jdk信任库 -->
keytool -import -alias sslTestServer_01 -file F:\ghj\prooooject\jar\test\server\sslTestServer_01.cer -keystore 'C:\Program Files\Java\jdk1.8.0_261\jre\lib\security\cacerts' -storepass changeit –v

2、 代码实现


import okhttp3.Call;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

import javax.net.ssl.*;
import java.io.FileInputStream;
import java.io.IOException;
import java.security.*;
import java.security.cert.CertificateException;

/**
 * @program: test
 * @description:
 * @author: Guanzi
 * @created: 2021/03/08 21:13
 */
public class HttpsUtils {

    private final static String TEST_URL = "https://192.168.1.127:8000/test/version";
    private final static String CLIENT_CA_PATH = "F:\\ghj\\prooooject\\jar\\test\\20210308\\180\\client\\sslTestClient_01.p12";
    private final static String KEY_STORE_TYPE = "PKCS12";
    private final static String TRUST_KEY_STORE_TYPE = "JKS";
    private final static String KEY_STORE_PWD = "test.123456";
    private final static String JRE_PATH = "C:\\Program Files\\Java\\jdk1.8.0_261\\jre\\lib\\security\\cacerts";
    private final static String DEFAULT_PWD = "changeit";

    /**
     * 初始化HTTPS实例(需要校验CA)
     */
    private static volatile OkHttpClient client;

    /**
     * ssl socket工厂(需要校验CA)
     */
    private static SSLSocketFactory sslSocketFactory = null;
    private static X509TrustManager trustManager = null;
    private static SSLContext  sslContext = null;


    public static void main(String[] args) throws IOException, UnrecoverableKeyException, CertificateException, NoSuchAlgorithmException, KeyStoreException, KeyManagementException {
        // 初始化
        httpsInit();
        // 发送请求方法1
        firstSendHttps();
        // 发送请求方法2
        // secondSendHttps();
    }

    /**
     * 方法 1
     * @return
     * @throws IOException
     */
    public static String firstSendHttps() throws IOException {
        SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext,
                SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
        CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(sslsf).build();
        try {
            HttpGet httpget = new HttpGet(TEST_URL);
            log.info("executing req:" + httpget.getRequestLine());
            CloseableHttpResponse response = httpclient.execute(httpget);
            try {
                HttpEntity entity = response.getEntity();
                if (entity != null) {
                    String res = EntityUtils.toString(entity);
                    log.info(res);
                    JSONObject datas = JSONObject.parseObject(res);
                    return datas.toJSONString();
                }
            } finally {
                response.close();
            }
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            httpclient.close();
        }
        return "";
    }

   /**
     * 方法 2
     * 此方法需要引入jar包。
     * <dependency>
     *   <groupId>com.squareup.okhttp3</groupId>
     *   <artifactId>okhttp</artifactId>
     *   <version>3.3.0</version>
     * </dependency>
     * @return
     * @throws IOException
     */
    public static String secondSendHttps() throws IOException {
        client = new OkHttpClient.Builder()
                .sslSocketFactory(sslSocketFactory,trustManager)
                .hostnameVerifier((String hostname, SSLSession session) -> true)
                .build();
        Request request = new Request.Builder().url(TEST_URL).build();
        Call call = client.newCall(request);
        Response response = call.execute();
        if(response.body() != null)
        {
            String result = response.body().string();
            //处理result
            log.info("okhttp req res:" + result);
            return result;
        }
        return "";
    }

    /**
     * 初始化方法。
     * @throws KeyStoreException
     * @throws IOException
     * @throws CertificateException
     * @throws NoSuchAlgorithmException
     * @throws UnrecoverableKeyException
     * @throws KeyManagementException
     */
    public static void httpsInit() throws KeyStoreException, IOException, CertificateException, NoSuchAlgorithmException, UnrecoverableKeyException, KeyManagementException {
        // 客户端证书类型
        KeyStore clientStore = KeyStore.getInstance(KEY_STORE_TYPE);
        // 加载客户端证书,即p12文件。
        clientStore
                .load(new FileInputStream(CLIENT_CA_PATH),
                        KEY_STORE_PWD.toCharArray());
        // 创建密钥管理工厂实例
        KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
        // 初始化客户端密钥库
        kmf.init(clientStore, KEY_STORE_PWD.toCharArray());
        KeyManager[] kms = kmf.getKeyManagers();
        // 创建信任库管理工厂实例
        TrustManagerFactory tmf = TrustManagerFactory
                .getInstance(TrustManagerFactory.getDefaultAlgorithm());
        // 信任库类型
        KeyStore trustStore = KeyStore.getInstance(TRUST_KEY_STORE_TYPE);
        // 加载信任库,即服务端公钥,jre安装目录。
        trustStore.load(new FileInputStream(JRE_PATH),
                DEFAULT_PWD.toCharArray());
        // 初始化信任库
        tmf.init(trustStore);
        TrustManager[] tms = tmf.getTrustManagers();
        // 建立连接,这里传TLS或SSL其实都可以的
        sslContext = SSLContext.getInstance("TLS");
        // 初始化SSLContext
        sslContext.init(kms, tms, new SecureRandom());
        try {
            sslSocketFactory = sslContext.getSocketFactory();
        } catch (Exception e) {
            e.printStackTrace();
        }
        trustManager = (X509TrustManager) tms[0];
        return;
    }

}

3、测试

image.png

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值