Как преобразовать JWK в открытый ключ через OpenSSL - PullRequest
1 голос
/ 12 апреля 2019

У меня есть JWE и в заголовке эфемерный открытый ключ.Итак, у меня есть координаты X и Y.

Мой вопрос в режиме оболочки, как преобразовать JWK в открытый ключ ECC в формате pem.

Например, здесь 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

Итак, открытый ключ 04 2918 fa7e 0754 b36f 614a e34d 925e 2395 58f0 39692d40 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

, как получить эти данные в режиме оболочки

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

1 Ответ

1 голос
/ 13 апреля 2019

Позвольте мне сначала кратко описать ваш целевой формат.То, что вы ищете, - это файл SubjectPublicKeyInfo (SPKI) в кодировке PEM.Кодировка PEM - это, по сути, кодировка DER (которая является двоичным форматом), а затем base64, закодированная с верхним и нижним колонтитулами.Структура SPKI определена в RFC5280 (см. Раздел 4.1):

https://tools.ietf.org/html/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
...