解决Https中使用TSLv1.2在java中通信的.crt .key .p12指定证书异常的问题

在项目中使用到了tlsv1.2来请求三方支付渠道,在拿到证书xxx.crt 和 密钥 xxx.key后,通过java代码配置keyStore和trustStore后一直报错,说加载证书失败,经查询发现java不能直接加载crt和key文件,需要转换成.p12或者.jks格式的文件

以下是转换方式:

.crt 转 .cer
openssl x509 -in xxx.crt -out xxx.cer -outform der
.cer 转 truststore
keytool -import -alias "merchant-support" -file xxx.cer -keystore xxx.truststore
.crt 转 .p12
openssl pkcs12 -export -in xxx.crt -inkey 20181030.key -out ms.p12 -name xxx

 

转换后如果直接用java加载keyStore和trustStore总是提示没有找到信任库,可以在项目发布的jdk中导入信任库,然后加载的时候不是用信任库,就会默认的使用jdk中的信任库。

如下,创建SSLContext

 public static SSLContext getSSLContext(String password, String keyStorePath, String trustKeyStorePath)
            throws Exception {
        //KeyStore用于存放证书,创建对象时 指定交换数字证书的加密标准
        File keyFile = new File(keyStorePath);
        InputStream keyStoreStream = new FileInputStream(keyFile);
        char[] pwdBArray = password.toCharArray();
        KeyStore keyStore = KeyStore.getInstance("PKCS12"); //KeyStore.getInstance(KeyStore.getDefaultType());
        log.info("========KeyStore 加载========== keyStorePath :{},password:{}", keyStorePath, password);
        keyStore.load(keyStoreStream, pwdBArray);
        //KeyManager选择证书证明自己的身份
        KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
        keyManagerFactory.init(keyStore, pwdBArray);
        KeyManager[] keyManagers = keyManagerFactory.getKeyManagers();


       /* //TrustManager决定是否信任对方的证书
        // 取到证书的输入流
        InputStream trustKeyStoreStream = new FileInputStream(trustKeyStorePath);
        KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType()); //KeyStore.getInstance(KeyStore.getDefaultType());
        log.info("========KeyStore 加载========== trustKeyStorePath :{},password:{}", trustKeyStorePath, password);
        trustStore.load(trustKeyStoreStream, pwdBArray);

        TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
        trustManagerFactory.init(trustStore);
        TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();*/
        SSLContext context = SSLContext.getInstance("TLSv1.2");
        context.init(keyManagers, null, new java.security.SecureRandom());

        keyStoreStream.close();
//        trustKeyStoreStream.close();
        return context;
    }

使用SSLContext ,

   String certFilePath = "/path/xxx.p12";
        String certClientFilePath = "/path/xxx.truststore";
        String certPassword = "xxx.p12 password";
        CloseableHttpClient httpClient;
        try {
            SSLContext sslContext = CertificateManager.getSSLContext(certPassword, certFilePath, certClientFilePath);
            SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
                    sslContext);
            httpClient = HttpClients.custom()
                    .setSSLSocketFactory(sslsf)
                    .setSslcontext(sslContext)
                    .build();
        } catch (Exception e) {
            e.printStackTrace();
        }

导入jdk证书
cd /usr/java/jre1.8.0_73/lib/security/
keytool -import -alias xxx -keystore cacerts -file /path/xxx.cer -trustcacerts
keytool -import -keystore cacerts -file /path/xxx.cer -trustcacerts
此时命令行会提示你输入cacerts证书库的密码,你敲入changeit就行了,这是java中cacerts证书库的默认密码

 

至此,https tlsv1.2通信已经可以通了

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值