# 简述
我们这里创建的并非 SSL 证书,而是一对公私钥,SSL 证书只能说是公私钥加密的一种应用。
# OpenSSL 工具
OpenSSL 是一个安全套接字层密码库,囊括主要的密码算法、常用密钥、证书封装管理功能及实现 ssl 协议。OpenSSL 整个软件包大概可以分成三个主要的功能部分:SSL 协议库 libssl、应用程序命令工具以及密码算法库 libcrypto。
# 生成私钥
openssl genrsa -out rsa_private_key.pem 2048 #生成密钥长度为 2048 的文本形式的私钥,如果不加长度,默认是 1024 长度的私钥。 |
# 生成公钥(由私钥计算产生)
首先要明白一点,公钥是公开透明的,私钥是独有的,我们想要的效果就是难以从公钥推出私钥,这就涉及到数学中的模运算了。从私钥生成公钥是通过正向的模运算算得的,计算机很快就能产生,但要反过来要计算机从公钥做逆模运算求得私钥,只要位数够长,就几乎是难以算出的。
因此公钥、私钥,都是成对出现的,公钥也是由私钥经过运算求得的。
openssl rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem #由私钥文件生成公钥 |
# 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 |
参数说明:
-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 #查看密钥库的密钥 |
keytool -exportcert -alias tomcat -keystore mykeystore.keystore -storepass 123456 -file key.cer #把证书从密钥库中导出来。 |
keytool -list -rfc -keystore mykeystore.keystore -storepass 123456 | openssl x509 -inform pem -pubkey #查看公钥 |
这里需要注意的是,我们前面创建的密钥库是 PKCS12 类型,这种密钥库直接就能够提取私钥。
openssl pkcs12 -in /home/momo/桌面/ssl/mykeystore.keystore -nocerts -nodes #直接提取私钥 |
# JKS 类型的密钥库提取公私钥
这种类型的密钥库,我们只需要将它转换成 pkcs12 类型的密钥库就能够正常提取公私钥了。
如图,直接提取是失败的
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 #提取私钥 |