我使用 RustCrypto 为 EC/P256 和 Ed25519 生成私钥并将其序列化为 PKCS#8,我得到 EC 密钥的 PKCS#8v1 和 Ed25519 的 PKCS#8v2。我想使用
openssl pkey
显示文件内容。
我将它们存储在 PEM 文件中,并尝试使用
openssl pkey
显示它们。看起来不支持 PKCS#8v2:
$ cat client-key-ec-p256.pem
-----BEGIN PRIVATE KEY-----
MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgBWozCxMmxGOxC1Sk
6BJewRNZyvTPuuDNDyGgtT5amLGhRANCAATvEOIa3laR/RoVYctOysCbFljPRVj1
wjYGoiTsqXMWDZKiVo9PsPEu19s9DD5b9YSimm9yDSQYb74ue0zk292Z
-----END PRIVATE KEY-----
$ openssl pkey -text -noout -in client-key-ec-p256.pem
Private-Key: (256 bit)
priv:
05:6a:33:0b:13:26:c4:63:b1:0b:54:a4:e8:12:5e:
c1:13:59:ca:f4:cf:ba:e0:cd:0f:21:a0:b5:3e:5a:
98:b1
pub:
04:ef:10:e2:1a:de:56:91:fd:1a:15:61:cb:4e:ca:
c0:9b:16:58:cf:45:58:f5:c2:36:06:a2:24:ec:a9:
73:16:0d:92:a2:56:8f:4f:b0:f1:2e:d7:db:3d:0c:
3e:5b:f5:84:a2:9a:6f:72:0d:24:18:6f:be:2e:7b:
4c:e4:db:dd:99
ASN1 OID: prime256v1
NIST CURVE: P-256
$ cat client-key-ed25519.pem
-----BEGIN PRIVATE KEY-----
MFECAQEwBQYDK2VwBCIEIGpXp9yLxq65o3YwgYdb9TgpvkR7ii1KSlHJIs+XulMX
gSEAJRnywWdPX1F+2E/n4rP4N36tcXyZkxyVFW+m1LFaCpw=
-----END PRIVATE KEY-----
$ openssl pkey -text -noout -in client-key-ed25519.pem
Could not read key from client-key-ed25519.pem
4037E1B9007F0000:error:1608010C:STORE routines:ossl_store_handle_load_result:unsupported:../cryptostore/store_result.c:151:
有什么原因吗?还是我错过了什么?
只有您的第一个(X9EC/P256)文件实际上是 PKCS8,它实际上没有版本;它的版本field是常数0。你的第二个(Ed25519)文件是RFC5958的v2,PKCS8的后继者,rust显然认为这里需要包含(预先计算的)公钥。是的 OpenSSL 不支持 RFC5958 v2。
您将要求表述为“显示文件内容”。您可以在 OpenSSL 中将其视为未知/任意 ASN.1 数据而不是密钥来做到这一点:
$ openssl asn1parse -i <77472637.2
0:d=0 hl=2 l= 81 cons: SEQUENCE
2:d=1 hl=2 l= 1 prim: INTEGER :01
5:d=1 hl=2 l= 5 cons: SEQUENCE
7:d=2 hl=2 l= 3 prim: OBJECT :ED25519
12:d=1 hl=2 l= 34 prim: OCTET STRING [HEX DUMP]:04206A57A7DC8BC6AEB9A3763081875BF53829BE447B8A2D4A4A51C922CF97BA5317
48:d=1 hl=2 l= 33 prim: cont [ 1 ]
# the OCTET STRING at offset 12 _contains_ (wraps) the privatekey so
$ openssl asn1parse -i -strparse 12 <77472637.2
0:d=0 hl=2 l= 32 prim: OCTET STRING [HEX DUMP]:6A57A7DC8BC6AEB9A3763081875BF53829BE447B8A2D4A4A51C922CF97BA5317
# the _implicit_ BIT STRING at offset 48 contains/wraps the publickey
# but there's no way for OpenSSL to understand its type so handle manually
$ openssl base64 -d <77472637.2 | tail -c +52 | xxd -p -c32
2519f2c1674f5f517ed84fe7e2b3f8377ead717c99931c95156fa6d4b15a0a9c
# (hl=2 plus 1 byte for the 'unused' octet in a bitstring is 51,
# plus 1 because `tail` is one-origin is 52)
但这并不是真正的编程或开发,而且可能偏离主题。
OTOH如果你想在OpenSSL中使用这个密钥,你需要删除[1] publicKey字段并将版本设置回0; OpenSSL 在使用时将重新生成公钥:
$ h=$(openssl base64 -d <77472637.2 | xxd -p -c83)
$ echo 302E020100${h:10:86} |xxd -p -r |openssl pkey -inform d -text # or other use or store or whatever
-----BEGIN PRIVATE KEY-----
MC4CAQAwBQYDK2VwBCIEIGpXp9yLxq65o3YwgYdb9TgpvkR7ii1KSlHJIs+XulMX
-----END PRIVATE KEY-----
ED25519 Private-Key:
priv:
6a:57:a7:dc:8b:c6:ae:b9:a3:76:30:81:87:5b:f5:
38:29:be:44:7b:8a:2d:4a:4a:51:c9:22:cf:97:ba:
53:17
pub:
25:19:f2:c1:67:4f:5f:51:7e:d8:4f:e7:e2:b3:f8:
37:7e:ad:71:7c:99:93:1c:95:15:6f:a6:d4:b1:5a:
0a:9c