Формат открытого ключа RSA

144

Где я могу найти документацию по формату открытого ключа 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?


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

Ян Бойд
источник

Ответы:

71

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

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

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

РЕДАКТИРОВАТЬ : после редактирования вы можете получить подробную информацию о своей 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
В этой статье упоминается, что формат OpenSSH является форматом, но не рассматриваются детали формата. Вместо этого упоминается, что формат полностью задокументирован в RFC 4253 - Протокол транспортного уровня Secure Shell (SSH) - раздел 6.6. Алгоритмы открытого ключа ; за исключением того, что я не могу найти там никакой документации. Я обновил вопрос, чтобы использовать чей-то открытый ключ RSA, который я нашел.
Ян Бойд
Я считаю, что первая ссылка переместилась на blog.oddbit.com/2011/05/08/converting-openssh-public-keys
mbargiel
1
Вы можете использовать openssl asn1parse -inform PEMс -----BEGIN RSA PUBLIC KEY----данными или любой другой структурой PEM. Намного проще, чем пытаться вручную манипулировать заголовками с помощью команд grep / tr / base64.
davenpcj 07
57

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

  • 00 00 00 07: префикс длиной четыре байта (7 байтов)
  • 73 73 68 2d 72 73 61: "ssh-rsa"
  • 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.

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

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

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

Ян Бойд
источник
1
RSA PUBLIC KEYследует форме ASN.1 (см. спецификацию PKCS), это не имеет ничего общего с форматом OpenSSH.
Бруно
3
Отличный ответ - большое спасибо. «Начальный ноль, потому что старший бит, но число положительное» попадает в формат ключа ssh-rsa в соответствии с источником. Самая полезная подсказка по этому поводу, которую я могу найти, - это комментарий в github.com/openssh/openssh-portable, в котором говорится: «/ * Если установлен MSB, добавить \ 0 * /» перед записью больших значений в формате ssh-rsa. Это кажется проблемой только для общедоступного модуля в 50% (?) Случаев и никогда не для общедоступной экспоненты из-за природы сгенерированных ключей RSA.
Тим Поттер
отличный ответ, о stringи mpint - он описан в RFC 4251, раздел 5, не нужно спрашивать :)
user1516873
10

Эталонный декодер 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-----

CSR

-----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

-----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-----
аниш
источник