如何通过openssl将jwk转换为公钥 [英] How to transform a jwk to public key over openssl

查看:142
本文介绍了如何通过openssl将jwk转换为公钥的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a JWE and in header an ephemeral public key. So I have coordinate X and Y.

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

My question in shell mode how to convert the JWK to ECC public key in pem format.

例如,这里有一个 jwk

For example, here a 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

所以公钥是042918 fa7e 0754 b36f 614a e34d 925e 239558f0 3969 2d40 493e f714 de65 c1c6 66f63400 db57 c193 564a 1349 5dbf 44ac 01f4511b 90a9 5024 0d83 d6b7 d99a e3b6 8605

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?

But I have the curve, the public key, I want to know how to generate a pem?

换句话说,

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

I have a file mykey.pub which contains this:

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

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

I execute this command to display the 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

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

So my question is if I have this data

> 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模式下检索这个

how to retrieve this in shell mode

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

推荐答案

让我先简要描述一下您的目标格式.您要获取的是 PEM 编码的 SubjectPublicKeyInfo (SPKI) 文件.PEM 编码本质上是 DER 编码(它是一种二进制格式),然后是带有页眉和页脚的 base64 编码.SPKI 结构在 RFC5280 中定义(见 4.1 节):

Let me first briefly describe your target format. What you are seeking to obtain is a PEM encoded SubjectPublicKeyInfo (SPKI) file. PEM encoding is essentially DER encoding (which is a binary format) and then base64 encoded with a header and footer. The SPKI structure is defined in RFC5280 (see section 4.1):

https://tools.ietf.org/html/rfc5280#section-4.1

   SubjectPublicKeyInfo  ::=  SEQUENCE  {
        algorithm            AlgorithmIdentifier,
        subjectPublicKey     BIT STRING  }

因此二进制 DER 编码中的第一个字节块由一个标头组成,该标头标识正在使用的算法(其中一部分包括曲线).最后一个字节是原始公钥(它是曲线上编码的 x 和 y 坐标).

So the first chunk of bytes in the binary DER encoding consists of a header that identifies the algorithm being used (and part of that includes the curve). The last bytes are the raw public key (which is an encoded x and y co-ordinate on the curve).

由于您的示例密钥与您要创建的密钥用于相同的曲线,因此它将具有相同的 AlgorithmIdentifier 标头字节.使用您的 mykey.pub 文件,我们可以将其转换为二进制 DER 格式:

Since your sample key is for the same curve as the key you want to create it will have the same AlgorithmIdentifier header bytes. Taking your mykey.pub file we can convert it to the binary DER format:

$ 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 个字节):

You can see the first bytes of the public key that you printed out above starting at offset 0x1a (i.e. 26 bytes in): 04 4c 65 30 .... The raw public key data extends all the way the end of the file and is 65 bytes long. This consists of a leading 0x04 byte followed by 32 bytes of x co-ordinate and 32 bytes of y co-ordinate. The leading 0x04 tells us how the co-ordinate is represented. 0x04 means "uncompressed" - which is handy because that's the simplest for us to deal with. We will also use uncompressed format for our target key. Therefore we need to take the first 26 bytes of header plus the 0x04 byte (so 27 bytes in total) from our sample key:

$ head -c 27 key.der >key.head

为了检查我们得到了我们所期望的:

And just to check we got what we were expecting:

$ 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 元素,您已经这样做了:

Now we create the x and y elements of our co-ordinate, which you already did:

$ echo -n "GCl++lQHb7NKYU3jXpKVI/BYaTlALT5JFPdl3sbB9mY=" | base64 -d >key.x
$ echo -n "ADRX25PBSlZJE79drET0ARtRqZAkUIMNt9aa2bbjBYY=" | base64 -d >key.y

然后将所有元素放在一起:

And then put all the elements together:

cat key.head key.x key.y >keynew.der

我们可以将 DER 格式的新密钥转换为 PEM 格式:

We can convert the new key in DER format to PEM format:

$ openssl ec -in keynew.der -inform DER -pubin -out keynew.pem

这给了我们:

-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEGCl++lQHb7NKYU3jXpKVI/BYaTlA
LT5JFPdl3sbB9mYANFfbk8FKVkkTv12sRPQBG1GpkCRQgw231prZtuMFhg==
-----END PUBLIC KEY-----

只是为了检查它看起来是否正常:

And just to check it looks sane:

$ 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

这篇关于如何通过openssl将jwk转换为公钥的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆