# 简述

我们这里创建的并非 SSL 证书,而是一对公私钥,SSL 证书只能说是公私钥加密的一种应用。

# OpenSSL 工具

OpenSSL 是一个安全套接字层密码库,囊括主要的密码算法、常用密钥、证书封装管理功能及实现 ssl 协议。OpenSSL 整个软件包大概可以分成三个主要的功能部分:SSL 协议库 libssl、应用程序命令工具以及密码算法库 libcrypto。

# 生成私钥

openssl genrsa -out rsa_private_key.pem 2048 #生成密钥长度为 2048 的文本形式的私钥,如果不加长度,默认是 1024 长度的私钥。

image-20220401133125996

# 生成公钥(由私钥计算产生)

首先要明白一点,公钥是公开透明的,私钥是独有的,我们想要的效果就是难以从公钥推出私钥,这就涉及到数学中的模运算了。从私钥生成公钥是通过正向的模运算算得的,计算机很快就能产生,但要反过来要计算机从公钥做逆模运算求得私钥,只要位数够长,就几乎是难以算出的。

因此公钥、私钥,都是成对出现的,公钥也是由私钥经过运算求得的。

openssl rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem  #由私钥文件生成公钥

image-20220401133142759

# Keytool 工具

Keytool 工具是 JDK 中自带的密钥管理工具,可以制作 Keystore(jks)格式的证书文件

由于使用 Keytool 工具制作的公钥和私钥默认是不可以导出的,需要从已经创建好的.keystore 文件中导出私钥。

https://www.cnblogs.com/mozq/p/11731598.html(keytool 使用大全)

# keystore(密钥库)是什么

这里需要注意的是,密钥库其实就是一种保存格式,通常为.jks、.pkcs12 之类的。如果不知道是其后缀名被改了,不知道是什么格式,使用 keytool list 就能知道了,然后根据它的类型,才决定能否获取私钥。
Keytool 将密钥(key)和证书(certificates)存在一个称为 keystore 的文件中,常用于 SSL 通信。在 KeyStore 中通常包含两种数据:
・密钥实体:密钥(对称加密)或者是公私钥(非对称加密)
・可信任证书实体:公钥和证书信息。

所有的数字证书是以一条一条 (采用别名区别) 的形式存入证书库的中,根据密钥库可以存储的条目以及密钥库如何存储条目,Java 中有几种不同类型的密钥库:JKS,JCEKS,PKCS12,PKCS11 和 DKS。最常见的是 JKS,JCEKS,PKCS12 类型

一个简单的理解就是:把证书和密钥等信息放到一块统一保存的文件,其中根据不同的密钥库类型,为密钥提高了不同程度的保密。

# JKS,Java Key Store

此密钥库是特定于 Java 平台的,通常具有 jks 的扩展名。此类型的密钥库可以包含私钥和证书,但不能用于存储密钥。由于它是 Java 特定的密钥库,因此不能在其他编程语言中使用。存储在 JKS 中的私钥无法在 Java 中提取。

目前,Java 中的默认密钥库类型是 JKS,即如果在使用 keytool 创建密钥库时未指定 - storetype,则密钥库格式将为 JKS.

# JCEKS,JCE 密钥库(Java Cryptography Extension KeyStore)

可以认为是增强式的 JKS 密钥库,支持更多算法。可以参考 com.sun.crypto.provider.JceKeyStore 类,此密钥库具有 jceks 的扩展名。可以放入 JCEKS 密钥库的条目是私钥,密钥和证书。此密钥库通过使用 Triple DES 加密为存储的私钥提供更强大的保护。

# PKCS12

PKCS12,一种标准的密钥库类型,可以在 Java 和其他语言中使用。它通常具有 p12 或 pfx 的扩展名。可以在此类型上存储私钥,密钥和证书。与 JKS 不同,PKCS12 密钥库上的私钥可以用 Java 提取。此类型是可以与其他语言(如 C,C ++ 或 C#)编写的其他库一起使用。
默认密钥库类型将在 Java 9 中更改为 PKCS12,因为与 JKS 相比,它具有增强的兼容性

# PKCS11

硬件密钥库类型。 为 Java 库提供了一个接口,用于连接硬件密钥库设备,如智能卡。 可以参考 sun.security.pkcs11.P11KeyStore 类。 此密钥库可以存储私钥,密钥和证书。 加载密钥库时,将从密钥库中检索条目,然后将其转换为软件成勋可识别的条目;

# BKS,BoucyCastle 密钥库

是一种密钥库格式,提供了流行的第三方 Java 加密库提供程序–BouncyCastle。它是一个类似于 Oracle JDK 提供的 JKS 的密钥库。支持存储密钥,私钥和证书,经常用于移动应用程序开发。

# 创建密钥库,提取公式钥

keytool 不能直接创建出一对公私钥,一般我们都是用它来创建一个自签名证书,然后从中提取公私钥的。

# 创建一个证书

keytool -genkeypair -alias "tomcat" -keyalg "RSA" -keystore "mykeystore.keystore"  -keysize 2048 -dname "CN=localhost, OU=localhost, O=localhost, L=SH, ST=SH, C=CN" -keypass "123456" -storepass 123456 -validity 360 -storetype PKCS12
#如上,我们就创建了一个 mykeystore.keystore 的密钥库,里面有一个别名为 tomcat 的 PKCS12 证书,其中使用的是 RSA 2048 的私钥, 该数字证书绑定的域名是 localhost。 密钥库的密码为 123456,证书密码也是 123456

image-20220401133542894

参数说明:

-genkeypair 表示要创建一个新的密钥

-dname  表示密钥的 Distinguished Names, 表明了密钥的发行者身份

CN=commonName 注:生成证书时,CN 要和服务器的域名相同,如果在本地测试,则使用 localhost

OU=organizationUnit

O=organizationName

L=localityName

S=stateName

C=country

-keyalg    使用加密的算法,这里是 RSA

-keysize 密钥长度

-alias     和 keystore 关联的别名,这个 alias 通常不区分大小写

-keypass   私有密钥的密码,这里设置为 123456

-keystore   密钥保存路径

-storepass  存取密码

-validity    该密钥的有效期 (默认为 90 天)

-storetype 密钥库类型

# 从密钥库中提取公私钥

keytool -list -keystore mykeystore.keystore  #查看密钥库的密钥

image-20220401133751716

keytool -exportcert -alias tomcat -keystore mykeystore.keystore -storepass 123456 -file key.cer #把证书从密钥库中导出来。

image-20220401133805333

keytool -list -rfc -keystore mykeystore.keystore -storepass 123456 | openssl x509 -inform pem -pubkey #查看公钥

image-20220401133815044

这里需要注意的是,我们前面创建的密钥库是 PKCS12 类型,这种密钥库直接就能够提取私钥。

openssl pkcs12 -in /home/momo/桌面/ssl/mykeystore.keystore -nocerts -nodes #直接提取私钥

image-20220401133823122

# JKS 类型的密钥库提取公私钥

这种类型的密钥库,我们只需要将它转换成 pkcs12 类型的密钥库就能够正常提取公私钥了。

如图,直接提取是失败的

image-20220401134026177

keytool -v -importkeystore -srckeystore mykeystore.jks -srcstoretype jks  -destkeystore mykeystore.pfx -deststoretype pkcs12   #将 jks 密钥库转成 pkcs12 类型
openssl pkcs12 -in /home/momo/桌面/ssl/mykeystore.pfx -nocerts -nodes   #提取私钥

image-20220401134044366