Keytool是什么
安装jdk之后默认就带有keytool这个工具,使用which命令可以查看具体命令路径。Keytool是一个简单的操作ssl证书的小工具。
which keytool
keytool -help
非法选项: -h
密钥和证书管理工具
命令:
-certreq 生成证书请求
-changealias 更改条目的别名
-delete 删除条目
-exportcert 导出证书
-genkeypair 生成密钥对
-genseckey 生成密钥
-gencert 根据证书请求生成证书
-importcert 导入证书或证书链
-importpass 导入口令
-importkeystore 从其他密钥库导入一个或所有条目
-keypasswd 更改条目的密钥口令
-list 列出密钥库中的条目
-printcert 打印证书内容
-printcertreq 打印证书请求的内容
-printcrl 打印 CRL 文件的内容
-storepasswd 更改密钥库的存储口令
使用 "keytool -command_name -help" 获取 command_name 的用法
Keytool使用说明
- 使用 keytool --help 可以查看相关帮助,如上图展示了相关的可用子命令。可以通过 keytool subCmd --help 查看具体每个子命令支持的用法。keytool --help 展示的是子命令,具体 keytool subCmd --help 会展示支持的选项。
keytool -genkey --help
keytool -genkeypair [OPTION]...
生成密钥对
选项:
-alias <alias> 要处理的条目的别名
-keyalg <keyalg> 密钥算法名称
-keysize <keysize> 密钥位大小
-sigalg <sigalg> 签名算法名称
-destalias <destalias> 目标别名
-dname <dname> 唯一判别名
-startdate <startdate> 证书有效期开始日期/时间
-ext <value> X.509 扩展
-validity <valDays> 有效天数
-keypass <arg> 密钥口令
-keystore <keystore> 密钥库名称
-storepass <arg> 密钥库口令
-storetype <storetype> 密钥库类型
-providername <providername> 提供方名称
-providerclass <providerclass> 提供方类名
-providerarg <arg> 提供方参数
-providerpath <pathlist> 提供方类路径
-v 详细输出
-protected 通过受保护的机制的口令
使用 "keytool -help" 获取所有可用命令
- 如上图,-genkey虽然没有出现在列表中,但是通过 --help 可发现其表示的是 -genkeypair。类似的缩略还有几个,此处不介绍(非必要)。
Keytool实战
创建证书
keytool -genkey -keyalg RSA -keystore server.keystore.jks -alias localhost -validity 1
- -genkey 是子命令,即创建密钥对(私钥+公钥,其中公钥本质即证书)。
- -keyalg 指定算法
- -keystore 指定密钥本文件(keystore可以理解为一个证书存储文件,一个文件内可以存储多个证书,每个证书使用一个alias标识)。每个keystore需要指定storepass进行基本的安全校验,每个alias(证书/密钥对)需要指定keypass用于基本的安全校验。
- -alias 指定本次创建的证书alias。
- 注意storepass和keypass不指定会在输入命令后通过交互方式输入。指定的keystore文件不存在,则输入的storepass为新密码,完成后会创建处store文件。若已存在,则输入的storepass需通过校验才能继续。
查看证书
keytool -list --help
keytool -list [OPTION]...
列出密钥库中的条目
选项:
-rfc 以 RFC 样式输出
-alias <alias> 要处理的条目的别名
-keystore <keystore> 密钥库名称
-storepass <arg> 密钥库口令
-storetype <storetype> 密钥库类型
-providername <providername> 提供方名称
-providerclass <providerclass> 提供方类名
-providerarg <arg> 提供方参数
-providerpath <pathlist> 提供方类路径
-v 详细输出
-protected 通过受保护的机制的口令
keytool -list -v -keystore server.keystore.jks
- 注意需要输入storepass。
导出证书
- 正如以上所说,store只是一个证书本。那么证书本身是什么样的呢。
keytool -exportcert -keystore server.keystore.jks -alias localhost -file server.cer
- 可以基于md5sum等指令验证server.cer的指纹是否和keytool -list打印的指纹一致。
- 需要注意的是,导出的证书不包含私钥。所以务必记住:仅包含单个alias的keystore和其导出的cer文件是不对等的(一个是公私钥对,另一个仅公钥)。
导入证书
- 既然可以从store导出证书,自然也可以导入。
-
keytool -import --help keytool -importcert [OPTION]... 导入证书或证书链 选项: -noprompt 不提示 -trustcacerts 信任来自 cacerts 的证书 -protected 通过受保护的机制的口令 -alias <alias> 要处理的条目的别名 -file <filename> 输入文件名 -keypass <arg> 密钥口令 -keystore <keystore> 密钥库名称 -storepass <arg> 密钥库口令 -storetype <storetype> 密钥库类型 -providername <providername> 提供方名称 -providerclass <providerclass> 提供方类名 -providerarg <arg> 提供方参数 -providerpath <pathlist> 提供方类路径 -v 详细输出 keytool -import -keystore server.keystore.jks -alias localhost3 -file server.cer 输入密钥库口令: 在别名 <localhost> 之下, 证书已经存在于密钥库中 是否仍要添加? [否]: y 证书已添加到密钥库中 keytool -list -keystore server.keystore.jks 输入密钥库口令: 密钥库类型: JKS 密钥库提供方: SUN 您的密钥库包含 3 个条目 localhost3, 2019-11-22, trustedCertEntry, 证书指纹 (SHA1): 54:16:B5:FB:DC:E8:3B:F1:59:77:F2:5D:01:84:6B:06:84:7C:D0:FB localhost2, 2019-11-22, PrivateKeyEntry, 证书指纹 (SHA1): 78:C9:08:4F:A3:3C:24:39:44:4C:99:23:B0:1B:01:46:CF:EC:37:44 localhost, 2019-11-22, PrivateKeyEntry, 证书指纹 (SHA1): 54:16:B5:FB:DC:E8:3B:F1:59:77:F2:5D:01:84:6B:06:84:7C:D0:FB
- 正如之前所讲,keystore和cer文件不对等,那么此处导入的仅仅是cer文件,和原先keystore中保存的还一样嘛。答案:不一样。如上图所示,localhost、localhost2、localhost3的类型并不一样。localhost和localhost2是PrivateKeyEntry,而localhost3是trustedCertEntry。
- PrivateKeyEntry的转移需要通过 keytool -importkeystore 指令操作。
-
打印和查看证书
-
keytool -printcert --help keytool -printcert [OPTION]... 打印证书内容 选项: -rfc 以 RFC 样式输出 -file <filename> 输入文件名 -sslserver <server[:port]> SSL 服务器主机和端口 -jarfile <filename> 已签名的 jar 文件 -v 详细输出 keytool -printcert -file server.cer 所有者: CN=zhao, OU=baidu, O=baidu_org, L=shanghai, ST=shanghai, C=cn 发布者: CN=zhao, OU=baidu, O=baidu_org, L=shanghai, ST=shanghai, C=cn 序列号: 6c7d478d 有效期开始日期: Fri Nov 22 17:22:07 CST 2019, 截止日期: Sat Nov 23 17:22:07 CST 2019 证书指纹: MD5: 27:F5:53:43:9C:3B:34:9E:57:1B:16:9B:C2:D9:BF:D6 SHA1: 54:16:B5:FB:DC:E8:3B:F1:59:77:F2:5D:01:84:6B:06:84:7C:D0:FB SHA256: 45:A3:76:1B:3C:63:FF:AC:DF:04:7B:14:53:27:1E:E8:0B:5A:CC:6A:6E:AD:6A:73:D2:D4:AC:58:E5:19:2B:28 签名算法名称: SHA256withRSA 版本: 3 扩展: #1: ObjectId: 2.5.29.14 Criticality=false SubjectKeyIdentifier [ KeyIdentifier [ 0000: 29 A6 40 94 4F E4 08 0E 6D CB 3E 71 15 F2 ED 45 ).@.O...m.>q...E 0010: E6 FB 98 5B ...[ ] ]
-
导出单独的key和cer文件
- 以上演示了导出cer文件,但是keytool默认无法导出key文件。首先我们需要转换为另外一种格式的store(即pkcs12)。
-
keytool -importkeystore -srcstoretype jks -srckeystore server/server.keystore.jks -deststoretype pkcs12 -destkeystore server/server.keystore.p12 -srcstorepass storepasswd -deststorepass storepasswd -srcalias kafka-server -srckeypass kafka-passwd -destkeypass storepasswd
- 注意,大多数工具对pkcs12格式的keystore要求storepass和keypass一致。因此需要指定同一个值,否则如上命令会报错。因此,为了统一管理,有时候即使是jks的store,我们也可以考虑将storepass和keypass设置为相同值。
-
openssl pkcs12 -nodes -in server/server.keystore.p12 -out server/server.pem
暂时写这么多,后续根据使用情况补充。