文章目录

  • About keytool
  • 生成密钥对
  • 证书相关操作
    • 导出证书
    • 导入证书
    • 查看证书
  • 罗列 KeyStore 的条目
  • 删除 KeyStore 条目
  • 证书请求
    • 生成证书请求
  • 附录
    • keytool 参数列表
    • Warning: JKS 密钥库使用专用格式 (JKS 转 PKCS#12)
    • OpenSSL 从 KeyStore 中读取公钥和证书
    • JAVA 从 KeyStore 中读取公私钥
    • JAVA 从证书中读取公钥
  • Reference
  • 修订日志

About keytool

Java Keytool 是一个可以生成公私钥对并将其存储到 [Java KeyStore](./About KeyStore.md) 的命令行工具. 是随 JDK (或者 JRE) 发布的.

λ keytool
密钥和证书管理工具命令:-certreq            生成证书请求-changealias        更改条目的别名-delete             删除条目-exportcert         导出证书-genkeypair         生成密钥对-genseckey          生成密钥-gencert            根据证书请求生成证书-importcert         导入证书或证书链-importpass         导入口令-importkeystore     从其他密钥库导入一个或所有条目-keypasswd          更改条目的密钥口令-list               列出密钥库中的条目-printcert          打印证书内容-printcertreq       打印证书请求的内容-printcrl           打印 CRL 文件的内容-storepasswd        更改密钥库的存储口令

本文会介绍这些命令的通常用法.

生成密钥对

使用 Java Keytool 最常见的场景大概就是生成公私钥对了, 生成的自签名密钥对被放到 Java KeyStore 文件中. 以下是一些用于生成密钥对的常用的参数:

λ keytool -genkeypair -help
keytool -genkeypair [OPTION]...生成密钥对选项:-alias <alias>                  生成的密钥被标识唯一的 Java KeyStore 的名称.-keyalg <keyalg>                密钥算法名称-keysize <keysize>              密钥位大小-sigalg <sigalg>                签名算法名称-destalias <destalias>          目标别名-dname <dname>                  唯一判别名, X.500 标准中的专有名词. 在 KeyStore 中, 这个名称与当前密钥对的别名关联. 在自签名的证书中, 这个名称同样也作为 issuer 和 subject-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 -genkeypair -alias my-very-first-key -keyalg RSA -keysize 2048 -dname "CN=caplike, OU=personal, O=caplike, L=Chengdu, ST=Unknown, C=CN" -keypass my-very-first-key-password -validity 100 -storetype JKS -keystore my-very-first-keystore.jks -storepass my-key-store-password

这样, 在当前目录下会生成一个名为 my-very-first-keystore.jks 的文件.

证书相关操作

导出证书

Java KeyTool 也能导出保存在 KeyStore 中的证书, 以下是导出证书的命令说明:

λ  keytool -exportcert -help
keytool -exportcert [OPTION]...导出证书选项:-rfc                            以 RFC 样式输出-alias <alias>                  要处理的条目的别名-file <filename>                输出文件名-keystore <keystore>            密钥库名称-storepass <arg>                密钥库口令-storetype <storetype>          密钥库类型-providername <providername>    提供方名称-providerclass <providerclass>  提供方类名-providerarg <arg>              提供方参数-providerpath <pathlist>        提供方类路径-v                              详细输出-protected                      通过受保护的机制的口令

例子:

keytool -exportcert -alias my-very-first-key -keypass my-very-first-key-password -storetype JKS -keystore my-very-first-keystore.jks -file my-very-first-cert.cert -storepass my-key-store-password
存储在文件 <my-very-first-cert.cert> 中的证书

当前目录下会生成一个名为 my-very-first-cert.cert 的文件.

导入证书

Java Keytool 也能将证书导入 KeyStore.

λ  keytool -importcert -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 -importcert -alias my-very-first-key -keypass my-very-first-key-password -storetype JKS -keystore my-second-keystore.jks -file another-cert.cert -rfc -storepass my-key-store-password

查看证书

λ keytool -printcert -help
keytool -printcert [OPTION]...打印证书内容选项:-rfc                        以 RFC 样式输出-file <filename>            输入文件名-sslserver <server[:port]>  SSL 服务器主机和端口-jarfile <filename>         已签名的 jar 文件-v                          详细输出

例子:

λ keytool -printcert -file my-very-first-cert.cert -v

控制台输出:

所有者: CN=caplike, OU=personal, O=caplike, L=Chengdu, ST=Unknown, C=CN
发布者: CN=caplike, OU=personal, O=caplike, L=Chengdu, ST=Unknown, C=CN
序列号: 309c2dc8
有效期为 Tue Jul 14 14:50:00 CST 2020 至 Thu Oct 22 14:50:00 CST 2020
证书指纹:MD5:  58:2D:17:7A:E6:57:06:F0:32:6A:5E:45:9B:9D:57:49SHA1: A3:41:6E:54:13:4A:80:83:BE:48:F2:B8:C0:A7:83:24:89:B4:65:F2SHA256: F2:42:37:FC:8E:AF:B2:12:B4:FC:9C:CB:8C:1E:4F:FC:B0:F5:DB:1D:F6:05:CC:1F:08:DC:EE:8E:B3:08:17:13
签名算法名称: SHA256withRSA
主体公共密钥算法: 2048 位 RSA 密钥
版本: 3扩展:#1: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: 84 A0 3B 38 46 80 A3 D6   2E 78 06 16 29 36 48 F5  ..;8F....x..)6H.
0010: EB A9 85 EF                                        ....
]
]

或者直接查看证书详细信息:

λ keytool -list -rfc -keystore authorization-server.jks
输入密钥库口令:
密钥库类型: PKCS12
密钥库提供方: SUN您的密钥库包含 1 个条目别名: authorization-server-jwt-keypair
创建日期: 2020-7-17
条目类型: PrivateKeyEntry
证书链长度: 1
证书[1]:
-----BEGIN CERTIFICATE-----
MIIDbzCCAlegAwIBAgIEAfMOsjANBgkqhkiG9w0BAQsFADBoMQswCQYDVQQGEwJD
TjEQMA4GA1UECBMHU2ljaHVhbjEQMA4GA1UEBxMHQ2hlbmdkdTEQMA4GA1UEChMH
Y2FwbGlrZTERMA8GA1UECxMIcGVyc29uYWwxEDAOBgNVBAMTB2NhcGxpa2UwHhcN
MjAwNzE3MDc0MzU0WhcNMzAwNzE1MDc0MzU0WjBoMQswCQYDVQQGEwJDTjEQMA4G
A1UECBMHU2ljaHVhbjEQMA4GA1UEBxMHQ2hlbmdkdTEQMA4GA1UEChMHY2FwbGlr
ZTERMA8GA1UECxMIcGVyc29uYWwxEDAOBgNVBAMTB2NhcGxpa2UwggEiMA0GCSqG
SIb3DQEBAQUAA4IBDwAwggEKAoIBAQCUvHlvPfO7+m1mlW68IFBnh0x4OGZkmbLG
JrsD3vToHmj+KksVxmeM60pVBxlNrxQ6eJMMnjoOYzIrZDmhbx3bhykx09LDE0xT
/t06/jQMWegVQUhZRH/58BlVMJ8lvukGnNamYua86EtXytI4pslMh5FRaCwVmwIk
lqohrf/qTuahNXgNRFSCHUAGYzJdR3f/N5KR08le71AJ3EXKBI9Umzh3kGqv3uZE
4h232qaeBqnUtyHZ6XCvNa5DHreYbGgr6XERAHp+108u+kQAG4IGzuE7XwIGPl6L
0b5+hoV7/vua40IgsC29zxSIPo9Ft/l7VhcSnQgdmKy46F52OoEVAgMBAAGjITAf
MB0GA1UdDgQWBBRqowFVjNkW77ZciS10KyMWs/3n2jANBgkqhkiG9w0BAQsFAAOC
AQEAJ+d+/0ss/Hl8IhPuIbH5Hh3MMxK8f02/QBPyJ5+ZJgt9k1BZc6/eMYbWd41z
05gb2m2arXfAS2HEdsY1pCfcssb85cVYUwMoDfK7pLRX34V0uhdUm0wqTBumIs2i
CCLCz7Eci4XpAv+RWHVKXbg+pP7GrKBh0iNYTuV+pDr+D7K6rZwGjYsGAqqpc1Lj
NNaN68pHhTnwXu4igM/gLsNRmR+2zXyJ1FZegnk0fsFWojOqHwCZxYli9245N4Hg
ePIVTvFTu+QzdLzFUcsGqhrynHfwQOvTyPMpaowpOsguNSzTdmRRK3QdtKHglE10
us40NUJZQgavCigGcVwAv/jCdA==
-----END CERTIFICATE-----*******************************************
*******************************************

罗列 KeyStore 的条目

可以用 -list 命令罗列 Java KeyStore 中的条目.

λ 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 -storetype JKS -keystore my-very-first-keystore.jks -storepass my-key-store-password

控制台输出:

λ keytool -list -storetype JKS -keystore my-very-first-keystore.jks -storepass my-key-store-password
密钥库类型: JKS
密钥库提供方: SUN您的密钥库包含 1 个条目my-very-first-key, 2020-7-14, PrivateKeyEntry,
证书指纹 (SHA1): A3:41:6E:54:13:4A:80:83:BE:48:F2:B8:C0:A7:83:24:89:B4:65:F2

也可以通过指定别名的方式显示列举某一条记录.

删除 KeyStore 条目

The Keytool has a command that can delete a key entry in a Java KeyStore. The Keytool command for deleting keys is -delete. Here is the format of the Keytool -delete command:

λ keytool -delete -help
keytool -delete [OPTION]...删除条目选项:-alias <alias>                  要处理的条目的别名-keystore <keystore>            密钥库名称-storepass <arg>                密钥库口令-storetype <storetype>          密钥库类型-providername <providername>    提供方名称-providerclass <providerclass>  提供方类名-providerarg <arg>              提供方参数-providerpath <pathlist>        提供方类路径-v                              详细输出-protected                      通过受保护的机制的口令

该命令会删除 JKS 文件中与当前别名匹配的条目.

keytool -delete -alias <alias> -storetype JKS -keystore <keystore> -storepass <keystore-pass>

证书请求

生成证书请求

-certreq 命令用于生成 “证书请求”. 证书请求是请求发证机构 (CA) 为你的组织创建公共证书的请求. 一旦创建, 证书请求应当被发送到你想创建证书的颁发机构去.

Before you can generate a certificate request for a private key, public key pair, you must have generated that private key, public key pair into the Keystore (or imported it). See elsewhere in this Java Keytool tutorial to see how to do that.

Here is the command format for generating a certificate request. Remember to remove all line breaks when trying out this command:

-certreq-alias alias-sigalg sigalg-file certreq_file-keypass keypass-storetype storetype-keystore keystore-storepass storepass-providerName provider_name-providerClass provider_class_name-providerArg provider_arg-v-protected-Jjavaoption

The arguments are explained in the Keytool Arguments section. Not all of these arguments are needed. Many are optional. The Keytool will tell you if you are missing a required argument.

Here is a Java Keytool -certreq command example:

"C:\\Program Files\Java\jdk1.8.0_111\bin\keytool"-certreq-alias testkey-keypass 123456-storetype JKS-keystore keystore.jks-storepass abcdef-file certreq.certreq

This command will generate a certificate request for the key stored with alias testkey in the keystore file keystore.jks, and write the certificate request into the file named certreq.certreq .

附录

keytool 参数列表

参数 描述
-alias key 的别名, 标识一条 key 记录.
-keyalg The name of the algorithm used to generate the key. A common value is RSA meaning the RSA algorithm should be used to generate the key pair.
-keysize 8 which aligns with a number of bytes. Additionally, different algorithms may only support certain preset key sizes. You will need to check what the key size should be for the key you want to generate.
-sigalg 密钥对的签名算法.
-dname 标识名 (X.500 标准), 会与这个密钥对关联, 如果是自签名证书, dname 也会作为 “issuer” 和 “subject” 字段的值. 由证书拥有者名称 (CN), 组织单位 (OU), 组织 (O), 州 (ST), 城市 (L), 国家/地区 © 组成.
-keypass 访问当前密钥对的密码.
-validity 关联这个密钥对的证书的有效期 (天).
-storetype KeyStore 的类型. 默认是 JKS. 也可以是其他类型例如 PKCS11.
-keystore KeyStore 文件名.
-file The name of the file to read from or write to (certificate or certificate request).
-storepass The password for the whole KeyStore. Anyone who wants to open this KeyStore later will need this password. The storepass is not the same as the keypass. The keypass password only counts for a single key. You will need both the KeyStore password and the key password to access any given key stored in a KeyStore.
-rfc If this flag is included (it has no value following it) then Keytool will use a textual format rather than binary format e.g. for export or import of certificates. 指定以Base64编码格式输出, 通常不设置
-providerName The name of the cryptographic API provider you want to use (if any) when generating the key pair. The provider name must be listed in the Java security property files for this to work.
-providerClass The name of the root class of the cryptographic API provider you want to use. Use this when the provider name is not listed in the Java security property files.
-providerArg 初始化的时候可以传递给 Provider 的参数 (如果需要).
-v verbose 以可读的方式打印额外信息.
-protected Specifies whether or not the KeyStore password should be provided by some external mechanism like a pin reader. Valid values are true and false.
-Jjavaoption 可用与传递给 JVM 的可选字符串参数.

Warning: JKS 密钥库使用专用格式 (JKS 转 PKCS#12)

如果生成密钥对或是读取公钥是看到如下提示:

Warning:

JKS 密钥库使用专用格式。建议使用 “keytool -importkeystore -srckeystore authorization-server.jks -destkeystore authorization-server.jks -deststoretype pkcs12” 迁移到行业标准格式 PKCS12。

说明我们需要把 KeyStore 的类格式换成 PKCS12, 执行如下命令即可:

λ keytool -importkeystore -srckeystore authorization-server.jks -destkeystore authorization-server.jks -deststoretype pkcs12 -destkeypass ********
输入源密钥库口令:
警告: PKCS12 密钥库不支持其他存储和密钥口令。正在忽略用户指定的-destkeypass值。
输入 <authorization-server-jwt-keypair> 的密钥口令
已成功导入别名 authorization-server-jwt-keypair 的条目。
已完成导入命令: 1 个条目成功导入, 0 个条目失败或取消Warning:
已将 "authorization-server.jks" 迁移到 Non JKS/JCEKS。将 JKS 密钥库作为 "authorization-server.jks.old" 进行了备份。

具体原因: JKS 全称 Java Key Store, 是 JAVA 密钥库的专属格式, 一般用于 Tomcat 服务器. PKCS#12 全称 Personal Information Exchange Syntax Standard, 描述了将用户公钥, 私钥, 证书和其他相关信息打包的语法. 和 JKS 一样都是二进制格式, 同时包含证书和私钥.


需要注意的是 PKCS#12 类型的密钥库不支持单独为 PrivateKey 指定密钥, 所以 -keypass 会被忽略. 密钥库的密钥就是 KeyPair 的密钥, 所以如果创建 PKCS#12 类型的密钥库, 命令应该形如:

keytool -genkeypair -alias authorization-server-jwt-keypair -keyalg RSA -keysize 2048 -dname "CN=caplike, OU=personal, O=caplike, L=Chengdu, ST=Sichuan, C=CN" -vali dity 3650 -storetype PKCS12 -keystore authorization-server.jks -storepass *******

Format Name Description
PKCS #7 Cryptographic Message Syntax Standard A PKCS #7 file can be used to store certificates,
which is a SignedData structure without data (just the certificates). The file name extension is usually .p7b, .p7c
PKCS #8 Private-Key Information Syntax Standard. Used to carry private certificate keypairs (encrypted or unencrypted).
PKCS #12 Personal Information Exchange Syntax Standard. Defines a file format commonly used to store private keys with accompanying public key certificates,
protected with a password-based symmetric key. It is the successor to PFX from Microsoft.
DER Distinguished Encoding Rules A binary format for keys or certificates. It is a message transfer syntax specified by the ITU in X.690.
PEM Privacy Enhanced Mail 一般是文本格式,
Base64 encoded DER certificates or keys, with additional header and footer lines.
The PEM private key format uses the header and footer lines:
-----BEGIN RSA PRIVATE KEY-----
-----END RSA PRIVATE KEY-----
The PEM public key format uses the header and footer lines:
-----BEGIN PUBLIC KEY-----
-----END PUBLIC KEY-----
The PEM certificate uses the header and footer lines:
-----BEGIN CERTIFICATE-----
-----END CERTIFICATE-----

Reference

  • SSL 证书格式普及: PEM, CER, JKS, PKCS12
  • PKCS

OpenSSL 从 KeyStore 中读取公钥和证书

我们还可以通过如下命令以命令行的形式直接从 KeyStore 中以 X.509 格式标准, 采用 PEM 的格式读取公钥和证书内容:

λ keytool -list -rfc --keystore authorization-server.jks | openssl x509 -inform pem -pubkey
输入密钥库口令:  ********
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0KwrwapB4g+jtX9UevtB
H/G9MAJLT+aJ+7D8WsKO4EEEVTnnS3PpO8TGQ5oYdWfHMQpJ3NhdNrMLz+6jX2on
zyRYvjBjCezIM3Ug3vXxm7JryDSvQZSyqcbXfAjrYQKaZOb2Ikgb6o3wvryJxE90
CIE1GtMcE6PKydg4tcKCR9ZYb5cw9Oehk7UI5GK8L17rF71YIWU0DQXAeHVhsSa7
/MNclfgAb5fJftwCzWOkP7dCfxuDfAWvKyko6BRnGVKReU5dXLbAU5PSqFcnaW1S
VqeHLSct1eKUoeDN7iUjuVim2UxFb2ZlIMIVBqle5WqZwFIVql0hOjzN2lC77X1P
/QIDAQAB
-----END PUBLIC KEY-----
-----BEGIN CERTIFICATE-----
MIIDbzCCAlegAwIBAgIEfy56hzANBgkqhkiG9w0BAQsFADBoMQswCQYDVQQGEwJD
TjEQMA4GA1UECBMHU2ljaHVhbjEQMA4GA1UEBxMHQ2hlbmdkdTEQMA4GA1UEChMH
Y2FwbGlrZTERMA8GA1UECxMIcGVyc29uYWwxEDAOBgNVBAMTB2NhcGxpa2UwHhcN
MjAwNzE3MDUyMjM3WhcNMzAwNzE1MDUyMjM3WjBoMQswCQYDVQQGEwJDTjEQMA4G
A1UECBMHU2ljaHVhbjEQMA4GA1UEBxMHQ2hlbmdkdTEQMA4GA1UEChMHY2FwbGlr
ZTERMA8GA1UECxMIcGVyc29uYWwxEDAOBgNVBAMTB2NhcGxpa2UwggEiMA0GCSqG
SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDQrCvBqkHiD6O1f1R6+0Ef8b0wAktP5on7
sPxawo7gQQRVOedLc+k7xMZDmhh1Z8cxCknc2F02swvP7qNfaifPJFi+MGMJ7Mgz
dSDe9fGbsmvINK9BlLKpxtd8COthAppk5vYiSBvqjfC+vInET3QIgTUa0xwTo8rJ
2Di1woJH1lhvlzD056GTtQjkYrwvXusXvVghZTQNBcB4dWGxJrv8w1yV+ABvl8l+
3ALNY6Q/t0J/G4N8Ba8rKSjoFGcZUpF5Tl1ctsBTk9KoVydpbVJWp4ctJy3V4pSh
4M3uJSO5WKbZTEVvZmUgwhUGqV7lapnAUhWqXSE6PM3aULvtfU/9AgMBAAGjITAf
MB0GA1UdDgQWBBSrIIuwp9u3nwm9PFP6wbabSWUsvTANBgkqhkiG9w0BAQsFAAOC
AQEAh+J/ghJbGDFaSUcbj0AyvMSMD2NjlpLrRNsneccztA6vuLdHVM8Ow5JIBdaN
55mS0eZwS9hwHiiJlkE43znh1PESZtltZN/bGtCtI/0DOQHEyamzXrSjigRX7W0Y
+71CwQbONcPVFXAAklxq1Pf51fQKs82GrR2TY97EWBofwqIzaAT6a7l+Bkqasr1A
6Q9aWbDC/QJhzWtEGMAYysuquEOBcfcfyBfm7y/FMqPoKCOI391KDERB7DC9+1l3
y0qEtVBR6Hp/w3iEABrPsBvoWMtqJUQtfQzmmYYTeupPnsiQC9hH1+4PxUbKiMl3
KKhFVqDr3Zt+8tZy8GUK05UGBw==
-----END CERTIFICATE-----

Reference

  • openssl

JAVA 从 KeyStore 中读取公私钥

/*** Description: 从证书中读取公钥和私钥** @return void* @author LiKe* @date 2020-07-14 15:49:15*/
public static void read() throws KeyStoreException, IOException, CertificateException, NoSuchAlgorithmException, UnrecoverableKeyException {final KeyStore keyStore = KeyStore.getInstance("JKS");keyStore.load(new FileInputStream("D:\\caplike\\coding\\temp\\my-very-first-keystore.jks"), "my-key-store-password".toCharArray());final PublicKey publicKey = keyStore.getCertificate("my-very-first-key").getPublicKey();System.out.println("PublicKey: ");System.out.println(Base64.getEncoder().encodeToString(publicKey.getEncoded()));final Key key = keyStore.getKey("my-very-first-key", "my-very-first-key-password".toCharArray());System.out.println("PrivateKey: ");System.out.println(Base64.getEncoder().encodeToString(key.getEncoded()));
}

控制台输出:

PublicKey:
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnXr2y4WHXd7zQYHLY8AaV1DeDJ+NDNJrRy++gGtXtgPqV81bDa/9VAap0fM3fmgVPzVBmG5ke/lKCAEGyvoOAD/eVADGi6yuyjcruFEjKOVk8ZVqA/1GNzuGzYzzQcSQ3Nd4BQape/qUfurnmVHEHPzG60vR1vinKm+llgUCf7GmSOiCjHq5FPCC5LrRJvmFE1UpSiuWbFIN+7Vb03PAgC70HWLk0eaY3hKD8T7DKYAWZmTBN4zZy9VbTFFigUcHb7OJ0vLaBaLOWqScYRyENE55xfGaZJd4CWyjr2e2GPCl8bab65R6XpovKhh4kDTbFpUABiGDMYo0jwCpDEQuOwIDAQAB
PrivateKey:
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCdevbLhYdd3vNBgctjwBpXUN4Mn40M0mtHL76Aa1e2A+pXzVsNr/1UBqnR8zd+aBU/NUGYbmR7+UoIAQbK+g4AP95UAMaLrK7KNyu4USMo5WTxlWoD/UY3O4bNjPNBxJDc13gFBql7+pR+6ueZUcQc/MbrS9HW+Kcqb6WWBQJ/saZI6IKMerkU8ILkutEm+YUTVSlKK5ZsUg37tVvTc8CALvQdYuTR5pjeEoPxPsMpgBZmZME3jNnL1VtMUWKBRwdvs4nS8toFos5apJxhHIQ0TnnF8Zpkl3gJbKOvZ7YY8KXxtpvrlHpemi8qGHiQNNsWlQAGIYMxijSPAKkMRC47AgMBAAECggEAZ/tOQ7oKVLAmvKVAL8AjZG4QABPFpaa2kQ10YwT9qEBTluAQdCw1QCsaLHfEt6FwDglTI5wYm0dSW5CZ9KJBZmbFnX/ZmVZPH1RoeM6SQameCmoW00WD/GpAqy6bXFy3LirTo7XvaN5e+KKQg8rajC1YBvtMNf5/GmUX18O9D6SqMcLfICqbEOjUfRT26gDRQGjZw2qgrzspY/qThNA9Qf/9Bbro4JHzjQJfX59VGeMVk/v5RsOWFGxFBE0zni7po6ODTVlCZT6T1RBS7Smw6y3mmfJ4mafFIciS0RI0ey0E3GLe1MpR0BLIkMz+d7/hPJbxIXLluljQ/s/sEQ7+QQKBgQDbP7LYpJIF8VtajO41M+TupKvdb8SSr3bGzicpzE+8VpjqcwSSiofrek3aFZzMpzA5v+uvfOflPEtLouY33ZlCgXjDYAN9a84qvpXqrMPUvWujx+Hm19pzLGLeFRrkNkiGYxX+HlC6CUjwwc7oEoYLw3TKWKklRhbTP/RuALHqoQKBgQC34K9j+TVwl/Sb1xVtqdrJmQlYp1PvZMf2+xS4gCWDN6ofSLJlHkFQ2l2EW11/4Ce+RYZ8K4bqR1zm/IS0wx/uFBo7ZVfBduo7VmoGOnf99SyrAhh3LUzmzSNNLiCPPXyoofrhYCT6nt9bvbK/gBy728hgpgunm2qzDSaWOj9nWwKBgQDDf+sz7psenXa+KYiG/D0Y5tExZOY9fiRFZbHaPYqj//veoqzjFo/YU3h0DG2Ct1nzRMUd+By3daoWSa1LB1gPy28pl8XE4oo15ze6yE7etgDzS9qNgtARfvSx3tPZxuWon1YPAG0vVfQqakba/Rl2B9VuUNySlgroV9DW/dunwQKBgQCLwgcNIZlwns6YtH3hADz/BYaJD4VIa31hR62UHjJk7aYsaQDOwpQ6c/6oXxlN3H3YrNdvAVZmMx91oXDsQ3K9biISCxEMRun5d9DWMxKIwBTXVZxq2M+ejUTLoMe2l7FsKtGZA46XvrFd9W0rCKDOWFqQuyQYnJQYy2IMxPD0CQKBgE8J/D5j7UDz4Hk675n3IUluEJEdBoopMqDj/avJU6bov9ZqdSlo2xqb6WluYO3mWofwpGGIzNnLwHSWVLTcoby0DMyI7Ze7EGyzjcWkKZyGFheWxWkcageXOgCV8P7iDIPm6EE1DS9IR9S5mkpaE+Jw+F4OT9v5OJlBYCmxquxH

JAVA 从证书中读取公钥

public void extractPublicKeyFromCertificateFile() {CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");//生成一个证书对象并使用从输入流 inStream 中读取的数据对它进行初始化。Certificate certificate = certificateFactory.generateCertificate(KeyStoreTools.class.getClassLoader().getResourceAsStream("public.cert"));PublicKey publicKey = certificate.getPublicKey();System.out.println("PublicKey: ");System.out.println(Base64.getEncoder().encodeToString(publicKey.getEncoded()));
}

Reference

  • Java Keytool
  • What is a Digital Signature?
  • 数字证书管理工具 openssl 和 keytool 的区别

修订日志

  • 2020-7-14 17:14:58

    • The Very First Version.
  • 2020-7-17 14:04:59
    • 新增 “附录” 章节.

Keytool 简述相关推荐

  1. SpringSecurity OAuth2 (7) 自定义 AccessToken 和 RefreshToken (JWT with RSA 签名)

    文章目录 AuthorizationServer 引言 AuthorizationServerTokenServices ResourceServerTokenServices TokenStore ...

  2. Azkaban任务调度工具简述

    小菜鸟的个人博客已经正式上线且对外开放啦- 博客访问地址:小菜鸟的大梦想 欢迎各位同学扫码关注本人公众号 ↓↓↓ 更多优质内容将 首发 公众号 Azkaban简述 Azkaban is a batch ...

  3. 简述计算机科学的核心内容,北京大学-计算机科学与技术(2018秋)作业及复习

    59.(第十章)外排序是指在排序前后,数据在外存上,排序时数据调入内存进行的排序方法. 60.(第十章)在选择排序.冒泡排序.归并排序中, 归并排序是空间复杂度最大的. 三.简答和程序题(共10题,每 ...

  4. 设计模式学习1:设计模式简述和设计模式原则

    设计模式简述 什么是设计模式? 软件工程中,设计模式(design pattern)是对软件设计中普遍存在(反复出现)的各种问题,所提出的解决方案. 设计模式的目的: 代码高可用(相同作用的代码能重复 ...

  5. Java中常见的锁简述

    在Java的应用中,或多或少的都会接触到一些锁,那么问题就来了,在Java中,常见的锁有哪些,都有什么样的作用?? 这里给大家简单的简述一下这些学常见的锁. 本文件所涉及到的锁: 1.公平锁 / 非公 ...

  6. 简述DataInputStream和DataOuputStream

    2019独角兽企业重金招聘Python工程师标准>>> Java开发中经常会用到IO流,那么就会碰到DataInputStream和DataOuputStream这两个包装类.下面就 ...

  7. 3des密钥生成 java_使用keytool生成3DES密钥

    keytool 简介 keytool生成3DES密钥 C:\Program Files\Java\jre1.8.0_161\bin>keytool -genseckey -alias test- ...

  8. 简要叙述matlab的含义,1,简述MATLAB组成部分? 2,说明使用M文件编辑/调试器的方法和优点? 3,存储在工作空间中的数组能编辑吗...

    匿名用户 1级 2012-05-17 回答 我也考这个....祝你好运 1,简述MATLAB组成部分? (1)开发环境(development Environment); (2)MATLAB数学函数库 ...

  9. 简述Linux和Windows下Python搭建步骤

    简述就Windows和Linux环境下安装Python的步骤. Python环境搭建首先到官网(www.python.org)下载相应的安装版本.主要分为Windows和Linux两种: 一.Linu ...

  10. android apk签名工具_关于keytool和jarsigner工具签名的使用小结

    在我们日常Android应用开发中,我们都要对我们开发的apk做签名处理,或者加固,增强我们apk的安全性,防止被逆向反编译,在apk签名这块,我们一般采用JDK自动工具来签名,下面就对相关工具做个简 ...

最新文章

  1. asp.net(C#)套用模板操作Excel。
  2. 得力助手 消防员的 消防机器人_消防机器人:消防员的“得力助手”(科技大观)...
  3. 为提高绩效,HR需要做的改进工作
  4. 赖美云的认证照_真人秀及综艺类双榜单TOP10嘉宾热度认证 赖美云双面魅力引热议...
  5. 推荐10个Github热门Python库,非常实用!
  6. 项目范围管理---定义范围
  7. java excel解析 poi_Java解析Excel之POI(一)
  8. [Elasticsearch] es 6.8 编译成功
  9. Spark集群无法停止的原因分析和解决
  10. 最好用的三款epub阅读器
  11. 软件测试 | 试用期总结万能模板
  12. bbed修改表记录内容系列三
  13. Python爬虫 爬取dota2官网英雄缺少英雄
  14. 20181012 excel 填充序列 快捷键
  15. android+蓝牙遥控器,一种通过蓝牙遥控安卓设备的方法与流程
  16. Always Day1 学会爱自己才能好好爱别人
  17. construct2制作炮击小箱子小游戏
  18. 如何实现报表的动态列展现效果
  19. 5-7万资金,可以创业吗?
  20. 计算机一级操作题文档,全国计算机一级EXCEL操作题

热门文章

  1. rs485全双工中只接一组_关于RS485接口的十八个经典问答!看你能答出几个!
  2. 一文读懂RFID射频识别技术
  3. Android开发之获取GPS位置案例源码详解
  4. 谷歌联合金山推出谷歌金山词霸
  5. Greenplum 安装部署 单机版安装(Linux)
  6. 奔图打印机linux驱动rpm,奔图P2500打印机驱动
  7. 安卓和win环境下扫描局域网下设备IP的工具
  8. 计算机没有无线网卡驱动程序,电脑上没有光驱怎么安装无线网卡驱动 - 驱动管家...
  9. 如何让百度谷歌快速shopex网店系统内容
  10. ubuntu安装无线网卡驱动(Ralink)