Java为什么需要证书?

出于安全的考虑,很多网站都使用https 协议,而要访问一个https 的站点则需要一个证书文件,这些证书文件由CA (Certificate Authority) 颁布, 各站点将这些认证过的证书放在各自的服务器上, 终端用户使用浏览器访问这些站点的时候,浏览器端安装了这些证书就可以和服务器进行安全的沟通了。
以上机制实现原理是: 数字证书是权威认证机构认证的站点的公钥, 站点把公钥给用户, 自己拥有私钥,通过公私钥的机制进行加密传输。
关于公私钥,数字证书可以参考:公钥、私钥、数字签名和数字证书的概念及解密 , https 证书可以参考:
https证书相关概念

这里重点要说明的是, 客户端需要使用证书文件访问服务端资源, 也就是说, 如果想访问一个https 的站点, 需要使用这个站点的公钥进行访问, 因为内容是加密的。

浏览器做为一种客户端,支持查看、下载和安装站点的证书的功能, 以Chrome 浏览器为例, 可以下载站点的证书, 详细可以参考:
如何在浏览器中下载网站的https证书

介绍了这么多, 你可能会问,这和本文有什么关系呢? 也就是Java和证书有什么关系呢?

Java语言提供了访问http以及https 的API, 很多基于Java 的应用都需要访问https 的资源, 比如:

  • Maven 从中央库(https://repo.maven.apache.org/maven2/)获取依赖
  • Jenkins在线安装插件(https://plugins.jenkins.io/)
    这些都是https 站点, 也都是需要对应的证书才能访问。如果没有证书, Java 会抛出如下的异常:
sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path

Java的证书管理机制

浏览器提供了查看证书文件的功能, 可以很容易的看到安装了多少证书以及每个证书的颁发机构, 有效日期等,比如在Chrome 中查看的证书信息如下图:

Java有没有function JAVA有没有证书_Java

这些证书是保存在使用的机器中的, 现在有一个问题, Java能读到本地机器的这些证书吗? 答案是Java有自己单独的证书管理机制。

JRE的安装目录jre\lib\security 中有一个 cacerts 文件, 将这个名字拆开来看 ca + certs , 就是CA机构颁发的证书,JRE安装的时候这个里面默认会包含一些常用的证书, 不包含在里面的证书站点需要单独安装。

Java有没有function JAVA有没有证书_Java有没有function_02

需要特别说明的是: JDK的安装目录也有一个JRE目录, 所有JDK安装之后, 其实是有两个JRE目录, 也就是会有两个cacerts 文件。这样可能遇到的问题是, 开发而言,一般使用JDK 下面的Java, 但是一般使用的时候吗可能使用到JRE下面的Java,所以,安装证书的时候, 保险起见, 是将证书同时安装到这两个证书库文件中。

Java 证书安装步骤

Java提供了keytool 工具, 用于将证书导入到Java 的证书库文件中。 首先的第一步是在浏览器端把证书下载下来, 这里以导入Maven 中央库的证书为例,使用Chrome下载证书。

  1. 在浏览器输入Maven 中央库地址: https://repo.maven.apache.org/maven2/
  2. 点击地址栏 左侧的小锁按钮,在弹出的下拉单中选择 “连接时安全的” 菜单,如下图:

Java有没有function JAVA有没有证书_Java_03

  1. 点击 “证书有效“
  2. Java有没有function JAVA有没有证书_jenkins_04

  3. 在弹出窗口中进入 ”详细信息“的标签页, 点击下方的“导出”按钮后, 选择一个本地的下载路径之后进行下载, 这里下载到 C盘的cert 目录, 证书文件名是:mvnrepo.crt
  4. Java有没有function JAVA有没有证书_Java有没有function_05

好了, 证书导出完成了, 接下来是把证书导入Java 的证书库文件,这里的Java安装目录是: C:\Program Files\Java

  1. 在命令终端执行如下命令: keytool -import -trustcacerts -alias mvnrepo -file c:\\cert\mvnrepo.crt -keystore "C:\Program Files\Java\jdk1.8.0_131\jre\lib\security\cacerts" -storepass changeit
  • alias 是这个证书在证书库的别名, 也就是唯一标识符。 这个名字需要唯一, 如果已经存在的话, 需要把旧的删除才能导入。
  • keystore 指定证书库文件的位置
  • storepass 证书库文件的密码, 默认是changeit
  1. 在命令终端执行如下命令: keytool -import -trustcacerts -alias mvnrepo -file c:\\cert\mvnrepo.crt -keystore "C:\Program Files\Java\jre1.8.0_211\lib\security\cacerts" -storepass changeit 上面也讲到了安装JDK 之后会有两个JRE目录, 保险起见是两边都安装, 也可以直接把证书文件复制过去。