蜗牛大师

吴庆龙的学习笔记

导航

keytool生成密钥

JDK11中,默认的密钥库类型为 PKCS12,它不支持单独给单个密钥设置密码,只支持给密钥库设置密码,而之前的 JKS 密钥库可以支持单独给每个密钥设置密码。
 
keytool 官当文档:https://docs.oracle.com/en/java/javase/11/tools/keytool.html
默认的密钥库位置是 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 类,发现它的实现类有三个:
  1. java.security.KeyStore.PrivateKeyEntry:存放一个加密的非对称加密的私钥,他还附带一个对应的公钥的证书链。是可以通过keytool -export命令导出对应证书。
  2. java.security.KeyStore.SecretKeyEntry:存放一个加密的对称加密的密钥。
  3. 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,对于加密解密来说很强大。
 

posted on 2021-01-26 14:45  蜗牛大师  阅读(2026)  评论(0编辑  收藏  举报