3

我有一个 JWE,并且在标题中有一个临时公钥。所以我有坐标X和Y。

我在 shell 模式下的问题是如何将 JWK 转换为 pem 格式的 ECC 公钥。

例如,这里有一个 jwk

{"epk":{"kty":"EC","crv":"P-256","x":"GCl--lQHb7NKYU3jXpKVI_BYaTlALT5JFPdl3sbB9mY","y":"ADRX25PBSlZJE79drET0ARtRqZAkUIMNt9aa2bbjBYY"}}

在我这样做之后

> # I convert the x coordonate from base64url to base64
> echo -n -e "GCl++lQHb7NKYU3jXpKVI/BYaTlALT5JFPdl3sbB9mY" | base64 -d | hexdump

0000000 2918 fa7e 0754 b36f 614a e34d 925e 2395
0000010 58f0 3969 2d40 493e f714 de65 c1c6 66f6
0000020

> echo -n -e "ADRX25PBSlZJE79drET0ARtRqZAkUIMNt9aa2bbjBYY" | base64 -d | hexdump

0000000 3400 db57 c193 564a 1349 5dbf 44ac 01f4
0000010 511b 90a9 5024 0d83 d6b7 d99a e3b6 8605
0000020

So the public key is 04 2918 fa7e 0754 b36f 614a e34d 925e 2395 58f0 3969 2d40 493e f714 de65 c1c6 66f6 3400 db57 c193 564a 1349 5dbf 44ac 01f4 511b 90a9 5024 0d83 d6b7 d99a e3b6 8605

但是我有曲线,公钥,我想知道如何生成一个pem?

换句话说,

我有一个 mykey.pub 文件,其中包含:

-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAETGUwowNEfqQ0LtHiMXJPY+Os5pXc
lsYCRPOi3F6K0n4k1RjJ7PGp/9RhZy3XS1yn1Qlu4hoCClHcc9rPXPn4fQ==
-----END PUBLIC KEY-----

我执行这个命令来显示公钥:

> openssl ec -in mykey.pub -pubin -text -noout
read EC key
Public-Key: (256 bit)
pub:
    04:4c:65:30:a3:03:44:7e:a4:34:2e:d1:e2:31:72:
    4f:63:e3:ac:e6:95:dc:96:c6:02:44:f3:a2:dc:5e:
    8a:d2:7e:24:d5:18:c9:ec:f1:a9:ff:d4:61:67:2d:
    d7:4b:5c:a7:d5:09:6e:e2:1a:02:0a:51:dc:73:da:
    cf:5c:f9:f8:7d
ASN1 OID: prime256v1
NIST CURVE: P-256

所以我的问题是我是否有这些数据

> openssl ec -in mykey.pub -pubin -text -noout
read EC key
Public-Key: (256 bit)
pub:
    04:4c:65:30:a3:03:44:7e:a4:34:2e:d1:e2:31:72:
    4f:63:e3:ac:e6:95:dc:96:c6:02:44:f3:a2:dc:5e:
    8a:d2:7e:24:d5:18:c9:ec:f1:a9:ff:d4:61:67:2d:
    d7:4b:5c:a7:d5:09:6e:e2:1a:02:0a:51:dc:73:da:
    cf:5c:f9:f8:7d
ASN1 OID: prime256v1
NIST CURVE: P-256

如何在 shell 模式下检索它

-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAETGUwowNEfqQ0LtHiMXJPY+Os5pXc
lsYCRPOi3F6K0n4k1RjJ7PGp/9RhZy3XS1yn1Qlu4hoCClHcc9rPXPn4fQ==
-----END PUBLIC KEY-----
4

1 回答 1

3

让我先简要描述一下您的目标格式。您要获取的是 PEM 编码的 SubjectPublicKeyInfo (SPKI) 文件。PEM 编码本质上是 DER 编码(这是一种二进制格式),然后使用页眉和页脚进行 base64 编码。SPKI 结构在 RFC5280 中定义(参见第 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
于 2019-04-12T23:26:41.707 回答