jvm导入cer证书步骤(亲测)


一、为什么要导入SSL证书?

网站安装SSL证书后,使用https加密协议访问网站,可激活客户端浏览器到网站服务器之间的"SSL加密通道"(SSL协议),实现高强度双向加密传输,防止传输数据被泄露或篡改。
Java 和 HTTP 的那些事(四) HTTPS 和 证书

二、文件形式的证书几大格式

作为文件形式存在的证书一般有这几种格式:

1.带有私钥的证书

由Public Key Cryptography Standards #12,PKCS#12标准定义,包含了公钥和私钥的二进制格式的证书形式,以pfx作为证书文件后缀名。

2.二进制编码的证书

证书中只有公钥,没有私钥,DER 编码二进制格式的证书文件,以cer作为证书文件后缀名。

3.Base64编码的证书

证书中只有公钥,没有私钥,BASE64 编码格式的证书文件,也是以cer作为证书文件后缀名。

由定义可以看出,只有pfx格式的数字证书是包含有私钥的,cer格式的数字证书里面只有公钥没有私钥。

在pfx证书的导入过程中有一项是“标志此密钥是可导出的。这将您在稍候备份或传输密钥”。一般是不选中的,如果选中,别人就有机会备份你的密钥了。如果是不选中,其实密钥也导入了,只是不能再次被导出。这就保证了密钥的安全。

如果导入过程中没有选中这一项,做证书备份时“导出私钥”这一项是灰色的,不能选。只能导出cer格式的公钥。如果导入时选中该项,则在导出时“导出私钥”这一项就是可选的。

如果要导出私钥(pfx),是需要输入密码的,这个密码就是对私钥再次加密,这样就保证了私钥的安全,别人即使拿到了你的证书备份(pfx),不知道加密私钥的密码,也是无法导入证书的。相反,如果只是导入导出cer格式的证书,是不会提示你输入密码的。因为公钥一般来说是对外公开的,不用加密。

三、业务场景介绍

在请求第三方api时,https路径请求抛出SSLHandshakeException,其大意是无法找到及验证有效证书,本机JVM需要先导入他们的证书才能识别出该域名

	HttpURLConnection conn = (HttpURLConnection) url.openConnection();
			// 设置超时间为120秒
			conn.setConnectTimeout(120 * 1000);
			// 120秒 从主机读取数据的超时时间(单位:毫秒)
			conn.setReadTimeout(120 * 1000);
			// 防止屏蔽程序抓取而返回403错误
			conn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");
			conn.setRequestProperty("lfwywxqyh_token",
					"SiGBCH6QblUHs7NiouV09rL6uAA3Sv0cGicaSxJiC/78DoWIMzVbW6VCwwkymYsZaxndDkYqkm4=");

			// 得到输入流,此处抛出异常
			InputStream inputStream = conn.getInputStream();
			// 获取自己数组
			byte[] getData = readInputStream(inputStream);

在这里插入图片描述

javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
        at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
        at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1917)
        at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:301)
        at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:295)
        at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1369)
        at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:156)
        at sun.security.ssl.Handshaker.processLoop(Handshaker.java:925)
        at sun.security.ssl.Handshaker.process_record(Handshaker.java:860)
        at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1043)
        at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1343)
        at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1371)
        at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1355)

四、导入cer证书步骤

1.准备工作

  • 找到证书存放路径
  • 通过运行工具类 ReadCert.java 查询出当前 jvm 所用的 jre 版本
  • 找到 jre 存放路径中 \lib\security\cacerts 路径

2.详细步骤

1.第三方cer证书存放路径
  • Windows: 我的证书存放路径 E:\download\test.cer
  • Linux: 我的证书存放路径 /tomcat/cert/test.cer
2.查询当前jvm所用的jdk及jre
  • 查看jvm 所用的 jre 版本信息命令:

java -XshowSettings:properties -version

其中 java.home字段即为当前使用的 jre

3.添加cer证书

Windows:

keytool -importcert -alias test.com -keystore C:\Program Files\Java\jre1.8.0_291\lib\security\cacerts -file E:\download\test.cer -trustcacerts

Linux:

keytool -importcert -alias test.com -keystore /usr/java/jdk1.8.0_101/jre/lib/security/cacerts -file /tomcat/cert/test.cer -trustcacerts

执行该命令后会出现如下结果,添加: y ,不继续添加: n
在这里插入图片描述
如果证书已经被添加过,则新添失败,并出现下面结果:
在这里插入图片描述
此时需要删掉错误的证书,重新添加

4.查询证书是否成功添加至jdk中
  • 获取当前jvm中存在的证书信息工具类如下:
class ReadCert {
  public static void main(String[] args) {
    System.out.println("hello");
    loadKeyStore();
  }
  private static void loadKeyStore() {
    String relativeCacertsPath = "/lib/security/cacerts".replace("/", File.separator);
    String filename = System.getProperty("java.home") + relativeCacertsPath;

    try {
      FileInputStream is = new FileInputStream(filename);
      KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType());
      String password = "changeit";
      keystore.load(is, password.toCharArray());
      PKIXParameters params = new PKIXParameters(keystore);

      Set<TrustAnchor> trustAnchors = params.getTrustAnchors();
      List<Certificate> certificates = trustAnchors.stream()
        .map(TrustAnchor::getTrustedCert)
        .collect(Collectors.toList());
      System.out.println(certificates);
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
}

运行结果中包含 jdk 中所有已添加的证书信息

  1. 对工具类运行结果分页显示,利于查找内容较多的文件或输出

java -jar MyTest.jar|less

  1. 查询是否已成功添加test.cer证书

jk上下,/test 搜索test

4.删除添加错误的证书

keytool -delete -alias test.com -keystore /usr/java/jdk1.8.0_101/jre/lib/security/cacerts

如果执行后未报错,则成功删除;报错可能提示该证书not exist ,也就是因为证书不存在所以删除失败。

5.查询执行过的keytool命令

history|grep keytool

利用管道搜索 筛选结果

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值