Почему два моих открытых ssh-ключа имеют одинаковое начало?

25

Я обновлял файл author_keys на моем сервере с открытым ключом для нового ноутбука, и я был удивлен, обнаружив, что два открытых ключа начали одинаково:

# key 1
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQ....
#
# key 2
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQ....

Что за история и AAAAB3...т. Д.? С некоторыми поисками в Интернете, я вижу, что другие ключи запускаются так же. Это объясняет алгоритм или версию или что-то?

Гейб Дуразо
источник
1
Что бы это ни стоило, у меня есть 7 ключей, сгенерированных за несколько лет на разных компьютерах, и все они начинаются с, AAAAB3NzaC1yc2EAAAAтак что я предполагаю, что это какой-то общий идентификатор типа / версии
алгоритма

Ответы:

24

На самом деле это заголовок, который определяет, что это за ключ. Если вы посмотрите раздел «Алгоритм открытого ключа» в RFC 4253, мы увидим, что для ключей RSA

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

 string    "ssh-rsa"
 mpint     e
 mpint     n

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

Фактически, если вы Base64 декодируете строку «B3NzaC1yc2E», вы увидите, что она переводится в ASCII как «ssh-rsa». Предположительно, «AAAA» представляет некоторый заголовок, поэтому приложение может знать, где именно в потоке данных начинать обработку ключа.

Скотт Пак
источник
Это кажется удивительно похожим на то, что я сказал, включая ссылку на RFC.
Жаворонки
@larsks: Видимо, вы нажали «Отправить», а я все еще писал свой.
Скотт Пак
15

Формат открытого ключа SSH задокументирован в RFC 4253 и кратко изложен здесь . Данные, закодированные PEM, состоят из нескольких пар (длина, данные), а первая пара кодирует имя алгоритма, которое будет примерно таким ssh-rsaили ssh-dsa.

Это означает, что начальная часть данных открытого ключа для всех ключей ssh ​​будет одинаковой.

larsks
источник
2

Я сделал излишнее глубокое погружение в формат после перехода по ссылкам Скотта для забавы. TLDR:

ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQ...
       |  "ssh-rsa"   |exponent|   modulus

RFC4231 определяет два используемых типа данных:

  • string: Двоичная строка произвольной длины. Строки могут содержать произвольные двоичные данные, включая нулевые и 8-битные символы. Они хранятся как uint32содержащие его длину

  • mpint: Представляет многократные целочисленные значения точности в формате дополнения до двух, сохраняются в виде строки, 8 бит на байт, сначала MSB. [...]

RFC4253 sec 6.6 говорит, что ключ закодирован как:

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

string    "ssh-rsa"
mpint     e
mpint     n

Здесь параметры 'e' и 'n' образуют блок ключа подписи. [Эд: но блоб, кажется, также содержит строку "ssh-rsa"...]

Результирующая подпись кодируется следующим образом:

string    "ssh-rsa"
string    rsa_signature_blob

Значение для 'rsa_signature_blob' кодируется как строка, содержащая s [Ed: не знаю, что такое s.] ( Которое является целым числом, без длин или дополнений, без знака и в сетевом порядке байтов).

"ssh-rsa"

Строка ssh-rsaпреобразуется в \x00\x00\x00\x07ssh-rsa, который затем кодируется в AAAAB3NzaC1yc2E=, поэтому все ключи ssh-rsa должны начинаться с этого.

eПубличный экспонент

Обычно что-то вроде 3, 17, 257, 65537. Эти числа кодируются как показано ниже (со смещением сверху)

  • 3 → '\x00\x00\x00\x01\x03'AAAABAw
  • 17 → '\x00\x00\x00\x01\x11'AAAABEQ
  • 257 → '\x00\x00\x00\x02\x01\x01'AAAACAQE
  • 65537 / 0x10001 → '\x00\x00\x00\x03\x01\x00\x01'AAAADAQAB

Итак, если вы видите «BAw», ваш показатель был 3, или «DAQAB» = 65537

n, модуль (произведение ваших двух секретных простых чисел, фактор это!)

AAABAQпосле вышесказанного означает, что длина вашего ключа составляет 2048 бит (и что ваш показатель степени был похож на DAQAB из-за заполнения base64). Весь остальной материал base64 - показатель степени, после него ничего нет.

Другие префиксы модуля, которые могут быть общими:

  • AAAAg 1024 бита, e = 0x10001
  • AAAQI: 2048 бит, e = 3
Ник Т
источник