Формат открытых ключей RSA

Где я могу найти документацию по формату открытого ключа RSA?

Открытый ключ RSA в формате OpenSSH:

SSH-RSA AAAAB3NzaC1yc2EAAAABJQAAAQB/nAmOjTmezNUDKYvEeIRf2YnwM9/uUG1d0BYsc8/tRtx + RGi7N2lUbp728MXGwdnL9od4cItzky/zVdLZE2cycOa18xBK9cOWmcKS0A8FYBxEQWJ/q9YVUgZbFKfYGaGQxsER + A0w/fX8ALuk78ktP31K69LcQgxIsl7rNzxsoOQKJ/CIxOGMMxczYTiEoLvQhapFQMs3FL96didKr/QbrfB1WT6s3838SEaXfgZvLef1YB2xmfhbT9OXFE3FXvh2UPBfN + ffE7iiayQf/2XR + 8j4N4bW30DiPtOQLGUrH1y5X/rpNZNlWW2 + jGIxqZtgWg7lTy3mXy5x836Sj/6L

Тот же открытый ключ, отформатированный для использования в Secure Shell (RFC 4716 - Формат файла открытого ключа Secure Shell (SSH)):

---- BEGIN SSH2 PUBLIC KEY ----
AAAAB3NzaC1yc2EAAAABJQAAAQB/nAmOjTmezNUDKYvEeIRf2YnwM9/uUG1d0BYs
c8/tRtx+RGi7N2lUbp728MXGwdnL9od4cItzky/zVdLZE2cycOa18xBK9cOWmcKS
0A8FYBxEQWJ/q9YVUgZbFKfYGaGQxsER+A0w/fX8ALuk78ktP31K69LcQgxIsl7r
NzxsoOQKJ/CIxOGMMxczYTiEoLvQhapFQMs3FL96didKr/QbrfB1WT6s3838SEaX
fgZvLef1YB2xmfhbT9OXFE3FXvh2UPBfN+ffE7iiayQf/2XR+8j4N4bW30DiPtOQ
LGUrH1y5X/rpNZNlWW2+jGIxqZtgWg7lTy3mXy5x836Sj/6L
---- END SSH2 PUBLIC KEY ----

Тот же открытый ключ, отформатированный как открытый ключ RSA (обратите внимание на пять - и без пробела):

-----BEGIN RSA PUBLIC KEY-----
MIIBCgKCAQEA+xGZ/wcz9ugFpP07Nspo6U17l0YhFiFpxxU4pTk3Lifz9R3zsIsu
ERwta7+fWIfxOo208ett/jhskiVodSEt3QBGh4XBipyWopKwZ93HHaDVZAALi/2A
+xTBtWdEo7XGUujKDvC2/aZKukfjpOiUI8AhLAfjmlcD/UZ1QPh0mHsglRNCmpCw
mwSXA9VNmhz+PiB+Dml4WWnKW/VHo2ujTXxq7+efMU4H2fny3Se3KYOsFPFGZ1TN
QSYlFuShWrHPtiLmUdPoP6CV2mML1tk+l7DIIqXrQhLUKDACeM5roMx0kLhUWB8P
+0uj1CNlNN4JRZlC7xFfqiMbFRU9Z4N6YwIDAQAB
-----END RSA PUBLIC KEY-----

Шестнадцатеричный дамп кодированных данных base-64:

00 00 00 07 73 73 68 2d 72 73 61 00 00 00 01 25 00 00 01 00 7f 9c 09
8e 8d 39 9e cc d5 03 29 8b c4 78 84 5f d9 89 f0 33 df ee 50 6d 5d d0 
16 2c 73 cf ed 46 dc 7e 44 68 bb 37 69 54 6e 9e f6 f0 c5 c6 c1 d9 cb
f6 87 78 70 8b 73 93 2f f3 55 d2 d9 13 67 32 70 e6 b5 f3 10 4a f5 c3 
96 99 c2 92 d0 0f 05 60 1c 44 41 62 7f ab d6 15 52 06 5b 14 a7 d8 19 
a1 90 c6 c1 11 f8 0d 30 fd f5 fc 00 bb a4 ef c9 2d 3f 7d 4a eb d2 dc 
42 0c 48 b2 5e eb 37 3c 6c a0 e4 0a 27 f0 88 c4 e1 8c 33 17 33 61 38 
84 a0 bb d0 85 aa 45 40 cb 37 14 bf 7a 76 27 4a af f4 1b ad f0 75 59 
3e ac df cd fc 48 46 97 7e 06 6f 2d e7 f5 60 1d b1 99 f8 5b 4f d3 97 
14 4d c5 5e f8 76 50 f0 5f 37 e7 df 13 b8 a2 6b 24 1f ff 65 d1 fb c8 
f8 37 86 d6 df 40 e2 3e d3 90 2c 65 2b 1f 5c b9 5f fa e9 35 93 65 59 
6d be 8c 62 31 a9 9b 60 5a 0e e5 4f 2d e6 5f 2e 71 f3 7e 92 8f fe 8b

я читал, что есть несколько форматов 🕗:

Ключевые данные могут быть закодированы тремя основными способами:

  • Бинарный DER-кодированный формат. Это иногда называют ASN.1 BER-кодированным
  • Формат PEM или base64. Это те же данные, что и файл в кодировке DER, но они кодируются в base64 с дополнительными строками верхнего и нижнего колонтитула.
  • XML формат

Если это ASN.1, гекс, конечно, не выглядит так.

Какой формат открытого ключа RSA?


Смотрите также

Ответ 1

Вы не можете просто изменить разделители от ---- BEGIN SSH2 PUBLIC KEY ---- до -----BEGIN RSA PUBLIC KEY----- и ожидать, что этого будет достаточно для преобразования из одного формата в другой (это то, что вы сделали в своем примере).

В этой статье есть хорошее объяснение обоим форматам.

То, что вы получаете в RSA PUBLIC KEY, ближе к содержимому PUBLIC KEY, но вам необходимо компенсировать начало структуры ASN.1, чтобы отразить тот факт, что PUBLIC KEY также имеет индикатор, указывающий, какой тип ключа (см. RFC 3447). Вы можете увидеть это с помощью openssl asn1parse и -strparse 19, как описано в этом ответе.

EDIT: после редактирования вы можете получить информацию о своей структуре RSA PUBLIC KEY, используя grep -v -- ----- | tr -d '\n' | base64 -d | openssl asn1parse -inform DER:

    0:d=0  hl=4 l= 266 cons: SEQUENCE          
    4:d=1  hl=4 l= 257 prim: INTEGER           :FB1199FF0733F6E805A4FD3B36CA68E94D7B974621162169C71538A539372E27F3F51DF3B08B2E111C2D6BBF9F5887F13A8DB4F1EB6DFE386C92256875212DDD00468785C18A9C96A292B067DDC71DA0D564000B8BFD80FB14C1B56744A3B5C652E8CA0EF0B6FDA64ABA47E3A4E89423C0212C07E39A5703FD467540F874987B209513429A90B09B049703D54D9A1CFE3E207E0E69785969CA5BF547A36BA34D7C6AEFE79F314E07D9F9F2DD27B72983AC14F1466754CD41262516E4A15AB1CFB622E651D3E83FA095DA630BD6D93E97B0C822A5EB4212D428300278CE6BA0CC7490B854581F0FFB4BA3D4236534DE09459942EF115FAA231B15153D67837A63
  265:d=1  hl=2 l=   3 prim: INTEGER           :010001

Чтобы декодировать формат ключа SSH, вам необходимо использовать спецификацию формата данных в RFC 4251 в сочетании с RFC 4253:

   The "ssh-rsa" key format has the following specific encoding:

      string    "ssh-rsa"
      mpint     e
      mpint     n

Например, в начале вы получаете 00 00 00 07 73 73 68 2d 72 73 61. Первые четыре байта (00 00 00 07) дают вам длину. Остальное - сама строка: 73 = s, 68 = h,... → 73 73 68 2d 72 73 61= ssh-rsa, за которой следует показатель длины 1 (00 00 00 01 25) и модуль длины 256 (00 00 01 00 7f ...).

Ответ 2

Начиная с декодированных данных base64 ключа rsa-ssh OpenSSL, я смог угадать формат:

  • 00 00 00 07: четырехбайтовый префикс длины (7 байтов)
  • 73 73 68 2d 72 73 61: "СШ-РСА"
  • 00 00 00 01: четырехбайтовый префикс длины (1 байт)
  • 25: показатель RSA (e): 25
  • 00 00 01 00: четырехбайтовый префикс длины (256 байт)
  • Модуль RSA (n):

    7f 9c 09 8e 8d 39 9e cc d5 03 29 8b c4 78 84 5f
    d9 89 f0 33 df ee 50 6d 5d d0 16 2c 73 cf ed 46 
    dc 7e 44 68 bb 37 69 54 6e 9e f6 f0 c5 c6 c1 d9 
    cb f6 87 78 70 8b 73 93 2f f3 55 d2 d9 13 67 32 
    70 e6 b5 f3 10 4a f5 c3 96 99 c2 92 d0 0f 05 60 
    1c 44 41 62 7f ab d6 15 52 06 5b 14 a7 d8 19 a1 
    90 c6 c1 11 f8 0d 30 fd f5 fc 00 bb a4 ef c9 2d 
    3f 7d 4a eb d2 dc 42 0c 48 b2 5e eb 37 3c 6c a0 
    e4 0a 27 f0 88 c4 e1 8c 33 17 33 61 38 84 a0 bb 
    d0 85 aa 45 40 cb 37 14 bf 7a 76 27 4a af f4 1b 
    ad f0 75 59 3e ac df cd fc 48 46 97 7e 06 6f 2d 
    e7 f5 60 1d b1 99 f8 5b 4f d3 97 14 4d c5 5e f8 
    76 50 f0 5f 37 e7 df 13 b8 a2 6b 24 1f ff 65 d1 
    fb c8 f8 37 86 d6 df 40 e2 3e d3 90 2c 65 2b 1f 
    5c b9 5f fa e9 35 93 65 59 6d be 8c 62 31 a9 9b 
    60 5a 0e e5 4f 2d e6 5f 2e 71 f3 7e 92 8f fe 8b
    

Ближайшее подтверждение моей теории я могу найти из RFC 4253:

Формат ключа "ssh-rsa" имеет следующую специфическую кодировку:

  string    "ssh-rsa"
  mpint     e
  mpint     n

Здесь параметры 'e' и 'n' образуют блок ключа подписи.

Но это не объясняет префиксы длины.


Взяв случайный RSA PUBLIC KEY я нашел (в вопросе), и расшифровав base64 в гекс:

30 82 01 0a 02 82 01 01 00 fb 11 99 ff 07 33 f6 e8 05 a4 fd 3b 36 ca 68 
e9 4d 7b 97 46 21 16 21 69 c7 15 38 a5 39 37 2e 27 f3 f5 1d f3 b0 8b 2e 
11 1c 2d 6b bf 9f 58 87 f1 3a 8d b4 f1 eb 6d fe 38 6c 92 25 68 75 21 2d 
dd 00 46 87 85 c1 8a 9c 96 a2 92 b0 67 dd c7 1d a0 d5 64 00 0b 8b fd 80 
fb 14 c1 b5 67 44 a3 b5 c6 52 e8 ca 0e f0 b6 fd a6 4a ba 47 e3 a4 e8 94 
23 c0 21 2c 07 e3 9a 57 03 fd 46 75 40 f8 74 98 7b 20 95 13 42 9a 90 b0 
9b 04 97 03 d5 4d 9a 1c fe 3e 20 7e 0e 69 78 59 69 ca 5b f5 47 a3 6b a3 
4d 7c 6a ef e7 9f 31 4e 07 d9 f9 f2 dd 27 b7 29 83 ac 14 f1 46 67 54 cd 
41 26 25 16 e4 a1 5a b1 cf b6 22 e6 51 d3 e8 3f a0 95 da 63 0b d6 d9 3e 
97 b0 c8 22 a5 eb 42 12 d4 28 30 02 78 ce 6b a0 cc 74 90 b8 54 58 1f 0f 
fb 4b a3 d4 23 65 34 de 09 45 99 42 ef 11 5f aa 23 1b 15 15 3d 67 83 7a 
63 02 03 01 00 01

Из RFC3447 - Стандарты криптографии с открытым ключом (PKCS) # 1: Спецификация криптографии RSA, версия 2.1:

A.1.1 Синтаксис открытого ключа RSA

Открытый ключ RSA должен быть представлен с помощью типа ASN.1 RSAPublicKey:

  RSAPublicKey ::= SEQUENCE {
     modulus           INTEGER,  -- n
     publicExponent    INTEGER   -- e
  }

Поля типа RSAPublicKey имеют следующие значения:

  • модуль является модулем RSA n.
  • publicExponent - открытый представитель RSA e.

Использование Microsoft отличной (и единственной реальной) документации ASN.1:

30 82 01 0a       ;SEQUENCE (0x010A bytes: 266 bytes)
|  02 82 01 01    ;INTEGER  (0x0101 bytes: 257 bytes)
|  |  00          ;leading zero because high-bit, but number is positive
|  |  fb 11 99 ff 07 33 f6 e8 05 a4 fd 3b 36 ca 68 
|  |  e9 4d 7b 97 46 21 16 21 69 c7 15 38 a5 39 37 2e 27 f3 f5 1d f3 b0 8b 2e 
|  |  11 1c 2d 6b bf 9f 58 87 f1 3a 8d b4 f1 eb 6d fe 38 6c 92 25 68 75 21 2d 
|  |  dd 00 46 87 85 c1 8a 9c 96 a2 92 b0 67 dd c7 1d a0 d5 64 00 0b 8b fd 80 
|  |  fb 14 c1 b5 67 44 a3 b5 c6 52 e8 ca 0e f0 b6 fd a6 4a ba 47 e3 a4 e8 94 
|  |  23 c0 21 2c 07 e3 9a 57 03 fd 46 75 40 f8 74 98 7b 20 95 13 42 9a 90 b0 
|  |  9b 04 97 03 d5 4d 9a 1c fe 3e 20 7e 0e 69 78 59 69 ca 5b f5 47 a3 6b a3 
|  |  4d 7c 6a ef e7 9f 31 4e 07 d9 f9 f2 dd 27 b7 29 83 ac 14 f1 46 67 54 cd 
|  |  41 26 25 16 e4 a1 5a b1 cf b6 22 e6 51 d3 e8 3f a0 95 da 63 0b d6 d9 3e 
|  |  97 b0 c8 22 a5 eb 42 12 d4 28 30 02 78 ce 6b a0 cc 74 90 b8 54 58 1f 0f 
|  |  fb 4b a3 d4 23 65 34 de 09 45 99 42 ef 11 5f aa 23 1b 15 15 3d 67 83 7a 
|  |  63 
|  02 03          ;INTEGER (3 bytes)
|     01 00 01

давая модуль и показатель открытого ключа:

  • модуль= 0xfb1199ff0733f6e805a4fd3b36ca68...837a63
  • показатель степени= 65,537

Обновление: моя расширенная форма этого ответа в другом вопросе

Ответ 3

Эталонный декодер CRL, CRT, CSR, NEW CSR, PRIVATE KEY, PUBLIC KEY, RSA, RSA Парсера открытого ключа

Открытый ключ RSA

-----BEGIN RSA PUBLIC KEY-----
-----END RSA PUBLIC KEY-----

Зашифрованный закрытый ключ

-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
-----END RSA PRIVATE KEY-----

CRL

-----BEGIN X509 CRL-----
-----END X509 CRL-----

ЭЛТ

-----BEGIN CERTIFICATE-----
-----END CERTIFICATE-----

КСО

-----BEGIN CERTIFICATE REQUEST-----
-----END CERTIFICATE REQUEST-----

НОВАЯ КСО

-----BEGIN NEW CERTIFICATE REQUEST-----
-----END NEW CERTIFICATE REQUEST-----

PEM

-----BEGIN RSA PRIVATE KEY-----
-----END RSA PRIVATE KEY-----

PKCS7

-----BEGIN PKCS7-----
-----END PKCS7-----

ЧАСТНЫЙ КЛЮЧ

-----BEGIN PRIVATE KEY-----
-----END PRIVATE KEY-----

DSA KEY

-----BEGIN DSA PRIVATE KEY-----
-----END DSA PRIVATE KEY-----

Эллиптическая кривая

-----BEGIN EC PRIVATE KEY-----
-----END EC PRIVATE KEY-----

Закрытый ключ PGP

-----BEGIN PGP PRIVATE KEY BLOCK-----
-----END PGP PRIVATE KEY BLOCK-----

Открытый ключ PGP

-----BEGIN PGP PUBLIC KEY BLOCK-----
-----END PGP PUBLIC KEY BLOCK-----