私钥可以有几种不同的记录形式,但最常见的形式是 PKCS#8,在 RFC 5208 中定义。
RFC 定义了两种结构形式。
PrivateKeyInfo ::= SEQUENCE {
version Version,
privateKeyAlgorithm PrivateKeyAlgorithmIdentifier,
privateKey PrivateKey,
attributes [0] IMPLICIT Attributes OPTIONAL }
“这个结构的版本号,以防它演变”,“如何识别使用什么解析器来读取 privateKey”,“一些东西,希望你能阅读它”,“一些关于这些东西的数据,也许” .
当 PEM 编码时,PrivateKeyInfo 获得标签“PRIVATE KEY”,如“BEGIN PRIVATE KEY”。你没有这些之一。
另一种形式是
EncryptedPrivateKeyInfo ::= SEQUENCE {
encryptionAlgorithm EncryptionAlgorithmIdentifier,
encryptedData EncryptedData }
“我如何加密东西”,“加密的东西”。
EncryptedPrivateKeyInfo 带有 PEM 标签“ENCRYPTED PRIVATE KEY”,这就是你所拥有的。
调查其中之一:
$ openssl asn1parse -i -dump < rsa.enc.p8
0:d=0 hl=4 l= 710 cons: SEQUENCE
4:d=1 hl=2 l= 64 cons: SEQUENCE
6:d=2 hl=2 l= 9 prim: OBJECT :PBES2
17:d=2 hl=2 l= 51 cons: SEQUENCE
19:d=3 hl=2 l= 27 cons: SEQUENCE
21:d=4 hl=2 l= 9 prim: OBJECT :PBKDF2
32:d=4 hl=2 l= 14 cons: SEQUENCE
34:d=5 hl=2 l= 8 prim: OCTET STRING
0000 - e9 37 68 99 cb 9c 4f 10- .7h...O.
44:d=5 hl=2 l= 2 prim: INTEGER :0800
48:d=3 hl=2 l= 20 cons: SEQUENCE
50:d=4 hl=2 l= 8 prim: OBJECT :des-ede3-cbc
60:d=4 hl=2 l= 8 prim: OCTET STRING
0000 - 16 ad ce 41 47 e8 ba 85- ...AG...
70:d=1 hl=4 l= 640 prim: OCTET STRING
<data_omitted />
数据是在基于密码的加密方案 2 (PBES2) 下加密的。输入密码/密码短语通过基于密码的密钥派生函数 2 (PBKDF2) 与盐(在加密时随机选择,但解密时必须相同)e9 37 68 99 cb 9c 4f 10 并使用迭代计数转换为密钥材料2048 (0x800)。该密钥用于 CBC 模式下的 TripleDES 加密,IV(在加密时随机选择,但必须与解密相同)为 16 ad ce 41 47 e8 ba 85。加密后的内容为 640 字节,然后会被解析为 PrivateKeyInfo 结构。
除了 PKCS#8 之外,传输私钥的唯一真正的其他选择是 PKCS#12/PFX,但该数据结构没有标准的 PEM 表示。最新版本的 PKCS#12 允许将数据加密为证书,采用 EnvelopedCMS/PKCS#7 的风格。
所以,对于一些简洁的答案:
-
ENCRYPTED PRIVATE KEY 表单已加密。
- 使用密码加密的可能性为 99.999%。
- 但可能有人使用密码短语以外的其他方式向 OpenSSL 教授 PBES2 KDF :)。
-
PRIVATE KEY 表单未加密。
-
RSA PRIVATE KEY 表单也未加密,但它是 PKCS#1 RSAPrivateKey,而不是 PKCS#8 PrivateKeyInfo。
- 如果 curl 没有提示您输入密码,则它不支持加密的私钥。
- 虽然没有密码短语的加密私钥并非不可能存在,但它绝对不常见,而且绝对不在 PEM 编码的有效负载中。