keytool生成密钥
JDK11中,默认的密钥库类型为 PKCS12,它不支持单独给单个密钥设置密码,只支持给密钥库设置密码,而之前的 JKS 密钥库可以支持单独给每个密钥设置密码。
默认的密钥库位置是 JavaHome 下的 ./lib/security/cacerts,查看默认密钥库的密钥:
./bin/keytool -list -keystore ./lib/security/cacerts
首先看一下 keytool 命令的参数有哪些?
# 使用 OHMYZSH 提示的 ➜ ~ keytool - -J -- specify java option -alias -- alias -certreq -- command to generate certificate signing request -delete -- command to delete entry -dest -- destination alias -dname -- X.500 distinguish name -export -- command to store certificate -file -- specify certificate file -file -- specify certificate signing request file -file -- specify identity database file -genkey -- command to generate a key pair -help -- command to print help message -identitydb -- command to read identity database -import -- command to import certificate or certificate chain -keyalg -- key algorithm -keyclone -- command to create new keystore entry -keypass -- old password for private key -keypass -- password for private key -keypasswd -- command to change password for private key -keysize -- key size -keystore -- keystore location -list -- command to print keystore entry -new -- new password -new -- nwe password for private key -new -- password for private key of new entry -noprompt -- disable interaction with the user -printcert -- command to print certificate in a human-readable format -rfc -- make certificate format printable as RFC 1421 -selfcert -- command to generate X.509 v1 self-signed certificate -sigalg -- signature algorithm -storepass -- password for keystore -storepasswd -- command to change password for keystore -storetype -- keystore type -trustcacerts -- use cacerts -v -- make certificate format human-readable -v -- verbose mode -validity -- valid days ➜ ~ keytool --help 密钥和证书管理工具 命令: -certreq 生成证书请求 -changealias 更改条目的别名 -delete 删除条目 -exportcert 导出证书 -genkeypair 生成密钥对 -genseckey 生成密钥 -gencert 根据证书请求生成证书 -importcert 导入证书或证书链 -importpass 导入口令 -importkeystore 从其他密钥库导入一个或所有条目 -keypasswd 更改条目的密钥口令 -list 列出密钥库中的条目 -printcert 打印证书内容 -printcertreq 打印证书请求的内容 -printcrl 打印 CRL 文件的内容 -storepasswd 更改密钥库的存储口令 使用 "keytool -?, -h, or --help" 可输出此帮助消息 使用 "keytool -command_name --help" 可获取 command_name 的用法。 使用 -conf <url> 选项可指定预配置的选项文件。
后面跟着英文注释,可以简单看一下。
如何生成密钥?
➜ ~ keytool -genkey -alias "key-1" -keystore "/Users/wu/java-key.keystore" -storepass 123456 您的名字与姓氏是什么? [Unknown]: ZhangSan 您的组织单位名称是什么? [Unknown]: Home-1 您的组织名称是什么? [Unknown]: Home-2 您所在的城市或区域名称是什么? [Unknown]: Beijing-1 您所在的省/市/自治区名称是什么? [Unknown]: Beijing-2 该单位的双字母国家/地区代码是什么? [Unknown]: CN CN=ZhangSan, OU=Home-1, O=Home-2, L=Beijing-1, ST=Beijing-2, C=CN是否正确? [否]: 是
执行完后会自动创建 java-key.keystore 这个文件,并且密钥库的密码是 123456,刚刚生成的密钥别名是 key-1。
执行命令后会让你填写一些信息,这些信息竟然可以随便填,没有校验。
查看密钥库里有哪些密钥?
➜ ~ keytool -keystore "/Users/wu/java-key.keystore" -storepass 123456 -list -v 密钥库类型: PKCS12 密钥库提供方: SUN 您的密钥库包含 1 个条目 别名: key-1 创建日期: 2021年1月25日 条目类型: PrivateKeyEntry 证书链长度: 1 证书[1]: 所有者: CN=ZhangSan, OU=Home-1, O=Home-2, L=Beijing-1, ST=Beijing-2, C=CN 发布者: CN=ZhangSan, OU=Home-1, O=Home-2, L=Beijing-1, ST=Beijing-2, C=CN 序列号: 32ddf5c6 生效时间: Mon Jan 25 10:16:52 CST 2021, 失效时间: Sun Apr 25 10:16:52 CST 2021 证书指纹: SHA1: 5A:22:06:04:E9:95:3A:BA:13:9B:52:F7:85:CD:E7:DF:87:27:F7:EB SHA256: D8:0D:0C:71:51:9E:B0:1F:1B:58:F8:0D:0B:00:28:B3:05:48:30:4C:FF:D9:F1:33:0F:E4:4C:16:24:22:6E:1E 签名算法名称: SHA256withDSA 主体公共密钥算法: 2048 位 DSA 密钥 版本: 3 扩展: #1: ObjectId: 2.5.29.14 Criticality=false SubjectKeyIdentifier [ KeyIdentifier [ 0000: 80 F7 D4 98 2F 5E 93 6C D8 5A D7 3C 9B B2 CB 1F ..../^.l.Z.<.... 0010: D6 96 66 EC ..f. ] ] ******************************************* *******************************************
可以发现,默认的密钥库类型是 PKCS12,可以通过 -storetype 来指定(如:-storetype JKS),默认的证书有效期是三个月,可以通过 -validity 来指定(如:-validity 180),默认的签名算法是 DES(SHA256withDSA),可以通过 -keyalg 来指定(如:-keyalg RSA,RSA默认的签名算法是 SHA256withDSA),其中的密钥长度可以使用 -keysize 参数来指定(如:-keyalg RSA -keysize 512,密钥算法有各自的密钥长度,不能随便指定)。
如果选择其它密钥,必须得保证在 KeyPairGenerator 中可用,比如 SHA512WITHRSA 就不可用,报错信息还挺友好。
➜ ~ keytool -genkey -alias "key-3" -keystore "/Users/wu/java-key.keystore" -storepass 123456 -keyalg SHA512WITHRSA keytool 错误: java.security.NoSuchAlgorithmException: SHA512WITHRSA KeyPairGenerator not available
如何非交互式的生成密钥?
keytool -genkey -alias "key-4" -keystore "/Users/wu/java-key.keystore" -storepass 123456 -dname "CN=ZhangSan, OU=Home-1, O=Home-2, L=Beijing-1, ST=Beijing-2, C=CN"
只需要用 -dname 参数将交互的数据填入即可。
如何删除密钥?
keytool -delete -alias "key-4" -keystore "/Users/wu/java-key.keystore" -storepass 123456
只需要把 -genkey 替换为 -delete,然后指定要删除的 key 的别名即可。密钥库的位置和密码是必须指定的。
如何导出证书?
➜ ~ keytool -export -alias "key-4" -keystore "/Users/wu/java-key.keystore" -storepass 123456 -file "/Users/wu/key-4.cer"
默认导出的密钥格式为二进制格式,可以使用 -rfc 进行指定为文本格式,后缀名没有要求,但是默认二进制格式的使用 .cer 或 .der 后缀,文本格式的使用 .crt 后缀。
如何导入证书?
keytool -import -alias key-4 -keystore ./key.keystore -file ./key-4.cer -storepass 123456
然后交互式提示你是否信任该证书,你可以使用 -noprompt 参数来直接确认导入。
导入后,证书列表如下:
key-3, 2021年1月25日, PrivateKeyEntry, 证书指纹 (SHA-256): 5A:D1:33:40:3A:52:3A:E2:62:61:6E:72:0F:E0:94:DE:D4:A9:FF:86:D9:DB:A7:BE:1A:4F:FE:B6:12:D1:1E:2C key-4, 2021年1月26日, trustedCertEntry, 证书指纹 (SHA-256): 24:B6:5A:8E:B7:6F:73:54:E8:6C:E8:76:68:50:82:36:F5:5E:56:56:91:F9:50:99:45:52:B0:95:CF:24:86:1C
可以发现默认生成的是 PrivateKeyEntry,导入的是 trustedCertEntry,分别是什么意思呢?
参看Java源码的 java.security.KeyStore.Entry 类,发现它的实现类有三个:
- java.security.KeyStore.PrivateKeyEntry:存放一个加密的非对称加密的私钥,他还附带一个对应的公钥的证书链。是可以通过keytool -export命令导出对应证书。
- java.security.KeyStore.SecretKeyEntry:存放一个加密的对称加密的密钥。
- java.security.KeyStore.TrustedCertificateEntry:存放受信任的证书。
转换密钥库类型:JKS 转 PKCS12
keytool -importkeystore -srckeystore /Users/wu/java-key.keystore -destkeystore /Users/wu/java-key.keystore -srcstoretype jks -deststoretype pkcs12
反过来也可以
keytool -importkeystore -srckeystore /Users/wu/java-key.keystore -destkeystore /Users/wu/java-key.keystore -srcstoretype pkcs12 -deststoretype jks
PKCS12密钥库生成 pem 证书:
openssl pkcs12 -in java-key.keystore -out java-key.pem -password pass:123456 -passin pass:123456 -passout pass:123456
注意:密钥库 java-key.keystore 中可以有多个密钥,但是生成的 java-key.pem 中只包含了密钥库中的第一个密钥。
可以学习一下 openssl,对于加密解密来说很强大。
------------------------------我是博客签名------------------------------
座右铭:不要因为知识简单就忽略,不积跬步无以至千里。
版权声明:自由转载-非商用-非衍生-保持署名。
本作品采用知识共享署名 4.0 国际许可协议进行许可。
----------------------------------------------------------------------
座右铭:不要因为知识简单就忽略,不积跬步无以至千里。
版权声明:自由转载-非商用-非衍生-保持署名。
本作品采用知识共享署名 4.0 国际许可协议进行许可。
----------------------------------------------------------------------