keytool 生成证书
.jks 和 .keystore 密钥库文件
jks 和 keystore 都是密钥库,可以用来存储证书和私钥。在 java 中一般使用 jks 密钥库,二者功能一样,可以互相转换。
.crt 和 .cer 证书文件
- .crt:扩展名 CRT 用于证书。证书可以是 DER 编码,也可以是 PEM 编码。扩展名 CER 和 CRT 几乎是同义词。这种情况在各种 unix/linux 系统中很常见。
- .cer:CRT 证书的微软型式。可以用微软的工具把 CRT 文件转换为 CER 文件(CRT 和 CER 必须是相同编码的,DER 或者 PEM)。扩展名为 CER 的文件可以被 IE 识别并作为命令调用微软的 cryptoAPI(具体点就是 rudll32.exe
keytool -help
bash
PS C:\Source> keytool -help
密钥和证书管理工具
命令:
-certreq 生成证书请求
-changealias 更改条目的别名
-delete 删除条目
-exportcert 导出证书
-genkeypair 生成密钥对
-genseckey 生成密钥
-gencert 根据证书请求生成证书
-importcert 导入证书或证书链
-importpass 导入口令
-importkeystore 从其他密钥库导入一个或所有条目
-keypasswd 更改条目的密钥口令
-list 列出密钥库中的条目
-printcert 打印证书内容
-printcertreq 打印证书请求的内容
-printcrl 打印 CRL 文件的内容
-storepasswd 更改密钥库的存储口令
使用 "keytool -command_name -help" 获取 command_name 的用法
keytool -genkeypair -help
bash
PS C:\Source> keytool -genkeypair -help
keytool -genkeypair [OPTION]...
生成密钥对
选项:
-alias <alias> 要处理的条目的别名
-keyalg <keyalg> 密钥算法名称(当使用 -genkeypair 参数时可选为 RSA 或 DSA)
-keysize <keysize> 密钥位大小
-sigalg <sigalg> 签名算法名称
-destalias <destalias> 目标别名
-dname <dname> 唯一判别名(CN:名字与姓氏(域名); OU:组织单位名称; O:组织名称; L:城市或区域名称; ST:省/市/自治区名称; C:该单位的双字母国家/地区代码)
-startdate <startdate> 证书有效期开始日期/时间
-ext <value> X.509 扩展
-validity <valDays> 有效天数(默认大约90天)
-keypass <arg> 密钥口令
-keystore <keystore> 密钥库名称
-storepass <arg> 密钥库口令
-storetype <storetype> 密钥库类型(常用的有JKS(默认),JCEKS,PKCS12(行业标准推荐),BKS,UBER 等。
KeyStore 的类型并不要求在文件名上体现,但是使用者要明确所使用的KeyStore的格式)
-providername <providername> 提供方名称
-providerclass <providerclass> 提供方类名
-providerarg <arg> 提供方参数
-providerpath <pathlist> 提供方类路径
-v 详细输出
-protected 通过受保护的机制的口令
使用 "keytool -help" 获取所有可用命令
KeyStore 和 TrustStore
- KeyStore 是服务器的密钥存储库,存服务器的公钥私钥证书
- TrustStore 是服务器的信任密钥存储库,存 CA 公钥,但有一部分人存的是客户端证书集合,这样并不合适
错误的使用:把 KeyStore 和 TrustStore 做成同一个 JKS 文件或 PKCS12 文件。通过导入客户端证书来实现验证客户端证书。实际生产中并不能这么做,客户端有成千上万个,你不可能都去导吧。
因为 KeyStore 和 TrustStore Java 中都可以通过 keytool 来管理的,所以在使用时多有混淆。记住以下几点,可以最大限度避免这些混淆:
- 如果要保存你自己的密码,秘钥和证书,应该使用 KeyStore,并且该文件要保持私密不外泄,不要传播该文件;
- 如果要保存你信任的来自他人的公钥和证书,应该使用 TrustStore,而不是 KeyStore;
- 在以上两种情况中的文件命名,要尽量提示其安全敏感程度而不是有歧义或者误导
- 比如使用 KeyStore 的场景把文件命名为 truststore.jks, 或者该使用 TrustStore 的情况下把文件命名为 keystore.jks 之类,这些用法都属于严重误导随后的使用者,有可能把比较私密的文件泄露出去;
- 拿到任何一个这样的文件时,确认清楚其内容然后决定怎样使用;
- 因为 KeyStore 文件既可以存储敏感信息,比如密码和私钥,也可以存储公开信息比如公钥,证书之类,所有实际上来讲,可以将 KeyStore 文件同样用做 TrustStore 文件, 但这样做要确保使用者很明确自己永远不会将该 KeyStore 误当作 TrustStore 传播出去。
一个 TrustStore 仅仅用来包含客户端信任的证书,所以,这是一个客户端 “所信任的来自其他人或者组织的信息” 的存储文件,而不能用于存储任何安全敏感信息,比如私钥(private key)或者密码。
客户端通常会包含一些大的 CA 机构的证书,这样当遇到新的证书时,客户端就可以使用这些 CA 机构的证书来验证这些新来的证书是否是合法的。
生成 Keystore 文件
bash
# 不能单纯的生成一个密钥库,生成密钥库的时候必须同时生成一个条目。下面这个命令在当前工作目录生成了一个密钥库文件 keystore.jks,里面存储了一个别名为 mengweijin 的密钥对
# 生成服务端密钥 jks 文件。注意:-storetype jks 参数,如果配置为 JKS,则在 SpringBoot 中也需要配置为对应的类型:key-store-type: JKS
# 在cmd中执行JDK中keytool的命令,创建一个文件名为 keystore.jks,别名为 mengweijin 的密钥库:
keytool -genkeypair -alias mengweijin -validity 36500 -keyalg RSA -dname "CN=mengweijin.com,OU=com.mengweijin,O=mengweijin,L=xi an,ST=shan xi, C=CN" -keypass 123456 -storepass 123456 -storetype JKS -keystore keystore.jks
Warning:
# 由于我们是在 SpringBoot 中配置 JKS 格式的密钥库,因此,不必按照下面的告警信息迁移到 PKCS12(.p12) 格式。如果需要迁移到 p12 格式,按照提示执行命令即可。
JKS 密钥库使用专用格式。建议使用 "keytool -importkeystore -srckeystore keystore.jks -destkeystore keystore.jks -deststoretype pkcs12" 迁移到行业标准格式 PKCS12。
PS C:\Source>
# 到这里已经在命令行执行目录下生成了 keystore.jks 密钥库文件。
使用 openssl 查看公钥
安装 openssl(如果电脑上已经安装过了,就可以跳过)
URL: http://slproweb.com/products/Win32OpenSSL.html
安装完成后,配置环境变量。把 openssl 安装路径 bin 的路径(例如 C:\Program Files\OpenSSL-Win64\bin)加入到操作系统的系统环境变量 Path 中。
关闭当前 cmd 窗口,或者重启电脑,重新打开一个 cmd,此时 openssl 命令就可以直接使用了。
查看公钥
bash
# 执行查看公钥的命令:
keytool -list -rfc --keystore keystore.jks -storepass 123456 | openssl x509 -inform pem -pubkey
# 生成的公钥(-----BEGIN PUBLIC KEY----- 和 -----END PUBLIC KEY----- 之间的是公钥,包括这两个头和尾)
keytool -v -importkeystore 密钥库格式类型转换
bash
# .jks 转 .p12 格式
keytool -v -importkeystore -srcstoretype JKS -srckeystore keystore.jks -srcstorepass 123456 -srcalias mengweijin -srckeypass 123456 -deststoretype PKCS12 -destkeystore keystore.p12 -deststorepass 123456 -destalias mengweijin -destkeypass 123456
# .jks 转 .keystore 同理,只是这个参数依然是这样:-deststoretype JKS
# 另外,所有 .keystore 与 .p12 之间的转换跟 .jks 与 .p12 之间的转换参数完全一样。
.p12 导出私钥文件( .key)
bash
# .key 文件不能通过 keytool 导出,只能通过代码或者 openssl 等工具导出。
openssl pkcs12 -in keystore.p12 -nocerts -nodes -out mengweijin.key -password pass:123456
PS C:\Source> openssl pkcs12 -help
Usage: pkcs12 [options]
Valid options are:
-nokeys Don't output private keys
-nodes Don't encrypt private keys
-in infile Input filename
-out outfile Output filename
-password val Set import/export password source
...... 这里省略了其他命令帮助信息
.jks 导出证书文件( .cer 或者 .crt )
bash
# 导出 .crt
keytool -v -export -alias mengweijin -keystore keystore.jks -storepass 123456 -rfc -file mengweijin.crt
# 导出 .cer
keytool -v -export -alias mengweijin -keystore keystore.jks -storepass 123456 -rfc -file mengweijin.cer
# 注意:.keystore 同理。