使用 KeyStore Explorer 签发 SAN 二级证书
需要生成一个 CA 根证书并以此签发二级证书,二级证书将作为服务端证书
服务端证书需要附加 SAN (Subject Alternative Name) (使用者可选名称) 信息
场景:
- 需要生成一个 CA 根证书并以此签发二级证书,二级证书将作为服务端证书
-
服务端证书需要附加 SAN (Subject Alternative Name) (使用者可选名称) 信息,示例如下
image.png
- 最终需要导出为 p12 格式的文件给 SpringBoot 使用
方案:
1. 下载安装
下载 KeyStore Explorer (一个 keytool 的 GUI 工具),其 GitHub 和官网地址如下
https://github.com/kaikramer/keystore-explorer
https://keystore-explorer.org/
个人建议去 GitHub 上下载 zip 包,虽然略微大一些,但可以免安装,解压即用
另外,以下内容均在 5.5.0 版本下截图演示
2. 新建 KeyStore
点击 create a new KeyStore
![](https://img.haomeiwen.com/i12185313/414061ec78fa5d07.png)
格式默认选择 pkcs #12 就行
![](https://img.haomeiwen.com/i12185313/aecbfd75fd66c8f4.png)
新建之后 Ctrl + S 保存一下,此时需要填写密码,这里自己随意设置(但要能记得住),此处演示均使用 123456
![](https://img.haomeiwen.com/i12185313/8595e03f5935b0b9.png)
保险起见,保存的时候 Files of Type 下拉框也选择 p12 那个,另外 File Name 需要自己加上 .p12 的后缀名(反正我这个版本不会自动加后缀)
![](https://img.haomeiwen.com/i12185313/620276c9d7130f89.png)
3. 创建根证书
首先需要创建一个密钥对 (Key Pair),空白处右键第一个就是了
![](https://img.haomeiwen.com/i12185313/29b9aca0e0e2ccd9.png)
此处可选算法,一般 RSA 2048 就行
![](https://img.haomeiwen.com/i12185313/84942f0dd836bf2f.png)
之后有几处需要注意,一个是有效期 Validity Period ,根据自己的需要填;再个就是 Name 最右边的
按钮,这个一定要点进去填;最后是 Add Extensions 按钮,这个目前可以先不填,但是生成二级证书添加 SAN 信息的时候就需要用到了
![](https://img.haomeiwen.com/i12185313/bfaab2b3081ed724.png)
点击上图 Name 最右边的按钮之后,就是这个窗口,这些都需要填,按自己的需求填写就好,此处我均填写为 ca
![](https://img.haomeiwen.com/i12185313/d55de091fa311410.png)
然后填写别名
![](https://img.haomeiwen.com/i12185313/499cb9e631d75942.png)
最后,这里是个坑,此处密钥对的密码可以设为和之前 KeyStore 不一样的,但是会影响到后面 SpringBoot 中的配置,如果只是个人学习使用,避免麻烦,那就设为和 KeyStore 一致的。
演示中密码均为 123456
![](https://img.haomeiwen.com/i12185313/41875b6d76531dd2.png)
然后就得到了一个 CA 根证书的密钥对
![](https://img.haomeiwen.com/i12185313/bf56848eaa14fb27.png)
莫得结束,此时只得到了密钥对,并不是证书,右键刚刚生成的密钥对,Export -> Export Certificate Chain
![](https://img.haomeiwen.com/i12185313/c75ca329916f0d2f.png)
之后选择格式和保存位置,格式一般默认就行,保存位置自己选
![](https://img.haomeiwen.com/i12185313/7ae98d40410aa27c.png)
目前得到的文件如下:
![](https://img.haomeiwen.com/i12185313/63c465c3f4da266d.png)
4. 创建并签发二级证书
如果是用过命令行工具的朋友应该知道签发二级证书的过程应该是 生成 key pair -> 生成 csr 请求 -> 签发并生成 cer 证书
不过 KeyStore Explorer 工具提供了一个便捷的方式,直接在 ca 密钥对上右键 -> Sign -> Sign New Key Pair 即可从生成密钥对到签发一气呵成
![](https://img.haomeiwen.com/i12185313/5098db4b867ff837.png)
之后需要输入这个密钥对的密码,和之前设置的一致就行
![](https://img.haomeiwen.com/i12185313/43c2b130e299bcde.png)
再之后的过程和上面创建新密钥对的过程差不多,但此时为了给 server 证书添加 SAN 附加信息,就需要用到 Add Extensions 按钮了
![](https://img.haomeiwen.com/i12185313/8e982ed3f7bac4c9.png)
点进来是这样的,选择使用标准模板
![](https://img.haomeiwen.com/i12185313/e276c26ad278fac3.png)
模板选择 SSL Server
![](https://img.haomeiwen.com/i12185313/fbd31bc973b86905.png)
然后会自动生成很多附加信息,选择 要修改的 Subject Alternative Name ,点击右边的修改按钮
![](https://img.haomeiwen.com/i12185313/857755befb2bd9ab.png)
此处就可以修改增删改 SAN 信息了
![](https://img.haomeiwen.com/i12185313/ff582231a0dbcfeb.png)
增改的窗口如下,常用的是 DNS 和 IP 两种,下方直接填写值即可
![](https://img.haomeiwen.com/i12185313/a4d38f39ebff8ae2.png)
演示中最终填写的 SAN 值如下
![](https://img.haomeiwen.com/i12185313/9c9e983b6f9917a6.png)
最后最后,别忘了点那个像书一样的按钮,填写 Name 部分,否则一定会报错无法继续的
![](https://img.haomeiwen.com/i12185313/bc5208cba67d18a2.png)
之后也会填写密码,为了方便可填为和 KeyStore 一致的,此处就不贴图了
现在得到了两个密钥对,server 就是带有 SAN 信息的服务端密钥对了,别忘了 Ctrl + S 保存一下
![](https://img.haomeiwen.com/i12185313/90851de96be0ea3c.png)
此时,我们可以像导出 ca 根证书那样导出这个 server 证书,但在 SpringBoot 中使用的话,并不需要这一步,直接把这份 test.p12 交给 SpringBoot 就好。
5. 在 SpringBoot 中使用
把这份 test.p12 放在 resources 目录下,然后在配置文件 application.properties 中这样写
#https端口号
server.port=443
#密钥库路径
server.ssl.key-store=classpath:test.p12
#密钥库密码
server.ssl.key-store-password=123456
#密钥库类型
server.ssl.keyStoreType=PKCS12
#使用的证书(密钥对)别名
server.ssl.keyAlias=server
如果之前创建密钥对的时候,没有把 密钥对的密码 填成和 密钥库密码 一致的,那就需要加一行
#密钥对密码
server.ssl.key-password=<要使用的密钥对的密码>
最后配成这样子,SpringBoot能够启动成功,应该就可以了
![](https://img.haomeiwen.com/i12185313/69902d6639868d8d.png)
当然,此时直接访问 localhost ,肯定会报 SSL 错误,这是因为 server 的上级证书不被我们的浏览器信任。所以我们可以把之前导出的 ca.cer 安装到 受信任的根证书颁发机构(这个位置不能选错,否则系统不会认为这是根证书)
![](https://img.haomeiwen.com/i12185313/2faa894e3af34a0c.png)
之后打开浏览器,访问 localhost
![](https://img.haomeiwen.com/i12185313/4cb5976a7b2b7312.png)
这个 SSL 的 demo 就传到 gitee 上面吧
后记
-
为什么不用 keytool 命令行工具?
之前笔者也试过用 keytool,在参照了大量博客的情况下,也成功了。但是 keytool 的命令行环境经常需要写一堆参数,用起来的体验也不是特别好,于是在了解到 KeyStore Explorer 的存在后,我立刻被它圈粉了。不过不知道是不是笔记本设置了全局缩放的原因,这个工具的在我的电脑开着中文输入法的时候会不时抽风,但相比于敲一堆又臭又长的命令,我可能更喜欢这个 GUI 界面。 -
p12 和 cer 的区别?
仅个人见解,不一定准确
p12 是一个包含了公私钥对的文件,而 cer 只包含了公钥证书 -
2021年,证书里面的 SAN 信息有多重要?
2022-06-02 补充:其实把证书的 CN (Common Name) 字段填写正确应该也能避免 NET::ERR_CERT_COMMON_NAME_INVALID 这个问题,具体请参考 https://www.cnblogs.com/iiiiher/p/8085698.html 中的 “浏览器如何验证证书” 部分
如果使用了上面的 demo,不妨试试把配置文件中的证书别名改成 ca (server.ssl.keyAlias=ca),即使是 ca.cer 那个根证书已经加入系统根证书域的情况下,使用 Edge 96.0.1054.43 (当然,Chromium 内核的) 访问 localhost,依然会报 NET::ERR_CERT_COMMON_NAME_INVALID
image.png
这和 ca 证书不受信任的 NET::ERR_CERT_AUTHORITY_INVALID 报错是不同的。说明即使证书受信任,但如果 SAN 信息对不上的话,依然会报错。可见目前证书中 SAN 信息的重要性