首先让我简要描述一下您的目标格式。您想要获取的是 PEM 编码的SubjectPublicKeyInfo (SPKI) 文件。 PEM 编码本质上是 DER 编码(这是一种二进制格式),然后使用页眉和页脚进行 Base64 编码。 SPKI 结构在 RFC5280 中定义(参见第 4.1 节):
https://www.rfc-editor.org/rfc/rfc5280#section-4.1 https://www.rfc-editor.org/rfc/rfc5280#section-4.1
SubjectPublicKeyInfo ::= SEQUENCE {
algorithm AlgorithmIdentifier,
subjectPublicKey BIT STRING }
因此,二进制 DER 编码中的第一个字节块包含一个标头,用于标识所使用的算法(其中一部分包括曲线)。最后一个字节是原始公钥(它是曲线上编码的 x 和 y 坐标)。
由于您的示例密钥与您要创建的密钥相同的曲线,因此它将具有相同的 AlgorithmIdentifier 标头字节。我们可以将您的 mykey.pub 文件转换为二进制 DER 格式:
$ openssl ec -in mykey.pub -pubin -outform DER -out key.der
我们来看一下内容:
$ hexdump -C key.der
00000000 30 59 30 13 06 07 2a 86 48 ce 3d 02 01 06 08 2a |0Y0...*.H.=....*|
00000010 86 48 ce 3d 03 01 07 03 42 00 04 4c 65 30 a3 03 |.H.=....B..Le0..|
00000020 44 7e a4 34 2e d1 e2 31 72 4f 63 e3 ac e6 95 dc |D~.4...1rOc.....|
00000030 96 c6 02 44 f3 a2 dc 5e 8a d2 7e 24 d5 18 c9 ec |...D...^..~$....|
00000040 f1 a9 ff d4 61 67 2d d7 4b 5c a7 d5 09 6e e2 1a |....ag-.K\...n..|
00000050 02 0a 51 dc 73 da cf 5c f9 f8 7d |..Q.s..\..}|
0000005b
您可以看到上面打印出的公钥的第一个字节,从偏移量 0x1a 开始(即 26 个字节):04 4c 65 30 ...
。原始公钥数据一直延伸到文件末尾,长度为 65 个字节。它由前导 0x04 字节组成,后跟 32 字节的 x 坐标和 32 字节的 y 坐标。前导 0x04 告诉我们坐标是如何表示的。 0x04 意味着“未压缩”——这很方便,因为这对我们来说是最简单的处理方式。我们还将使用未压缩的格式作为目标密钥。因此,我们需要从示例密钥中获取标头的前 26 个字节加上 0x04 字节(总共 27 个字节):
$ head -c 27 key.der >key.head
只是为了检查我们是否得到了我们所期望的:
$ hexdump -C key.head
00000000 30 59 30 13 06 07 2a 86 48 ce 3d 02 01 06 08 2a |0Y0...*.H.=....*|
00000010 86 48 ce 3d 03 01 07 03 42 00 04 |.H.=....B..|
0000001b
现在我们创建坐标的 x 和 y 元素,您已经这样做了:
$ echo -n "GCl++lQHb7NKYU3jXpKVI/BYaTlALT5JFPdl3sbB9mY=" | base64 -d >key.x
$ echo -n "ADRX25PBSlZJE79drET0ARtRqZAkUIMNt9aa2bbjBYY=" | base64 -d >key.y
然后将所有元素放在一起:
cat key.head key.x key.y >keynew.der
我们可以将 DER 格式的新密钥转换为 PEM 格式:
$ openssl ec -in keynew.der -inform DER -pubin -out keynew.pem
这给了我们:
-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEGCl++lQHb7NKYU3jXpKVI/BYaTlA
LT5JFPdl3sbB9mYANFfbk8FKVkkTv12sRPQBG1GpkCRQgw231prZtuMFhg==
-----END PUBLIC KEY-----
只是为了检查它看起来是否正常:
$ openssl ec -in keynew.pem -pubin -noout -text
read EC key
Public-Key: (256 bit)
pub:
04:18:29:7e:fa:54:07:6f:b3:4a:61:4d:e3:5e:92:
95:23:f0:58:69:39:40:2d:3e:49:14:f7:65:de:c6:
c1:f6:66:00:34:57:db:93:c1:4a:56:49:13:bf:5d:
ac:44:f4:01:1b:51:a9:90:24:50:83:0d:b7:d6:9a:
d9:b6:e3:05:86
ASN1 OID: prime256v1
NIST CURVE: P-256