СофтХабрахабр

[Перевод] Рукопожатие SSH простыми словами

Secure Shell (SSH) — широко используемый протокол транспортного уровня для защиты соединений между клиентами и серверами. Это базовый протокол в нашей программе Teleport для защищённого доступа к инфраструктуре. Ниже относительно краткое описание рукопожатия, которое происходит перед установлением безопасного канала между клиентом и сервером и перед началом полного шифрования трафика.

Обмен версиями

Рукопожатие начинается с того, что обе стороны посылают друг другу строку с номером версии. В этой части рукопожатия не происходит ничего чрезвычайно захватывающего, но следует отметить, что большинство относительно современных клиентов и серверов поддерживают только SSH 2.0 из-за недостатков в дизайне версии 1.0.

Обмен ключами

В процессе обмена ключами (иногда называемого KEX) стороны обмениваются общедоступной информацией и выводят секрет, совместно используемый клиентом и сервером. Этот секрет невозможно обнаружить или получить из общедоступной информации.

Инициализация обмена ключами

Обмен ключами начинается с того, что обе стороны посылают друг другу сообщение SSH_MSG_KEX_INIT со списком поддерживаемых криптографических примитивов и их предпочтительным порядком.

В таблице ниже перечислены криптографические примитивы, которые поддерживает Teleport. Криптографические примитивы должны установить строительные блоки, которые будут использоваться для обмена ключами, а затем полного шифрования данных.

Криптографические примитивы Teleport по умолчанию

Инициализация протокола Диффи — Хеллмана на эллиптических кривых

Поскольку обе стороны используют один и тот же алгоритм для выбора криптографических примитивов из списка поддерживаемых, после инициализации можно немедленно начать обмен ключами. Teleport поддерживает только протокол эллиптических кривых Диффи-Хеллмана (Elliptic Curve Diffie-Hellman, ECDH), так что обмен ключами начинается с того, что клиент генерирует эфемерную пару ключей (закрытый и связанный с ним открытый ключ) и отправляет серверу свой открытый ключ в сообщении SSH_MSG_KEX_ECDH_INIT.

Это чрезвычайно затрудняет проведение класса атак, где злоумышленник пассивно записывает зашифрованный трафик с надеждой украсть закрытый ключ когда-нибудь в будущем (как предусматривает закон Яровой — прим. Стоит подчеркнуть, что эта ключевая пара эфемерна: она используется только для обмена ключами, а затем будет удалена. Очень трудно украсть то, чего больше не существует. пер.). Это свойство называется прямой секретностью (forward secrecy).

Рис. 1. Генерация сообщения инициализации обмена ключами

Ответ по протоколу Диффи — Хеллмана на эллиптических кривых

Сервер ждёт сообщение SSH_MSG_KEX_ECDH_INIT, а при получении генерирует собственную эфемерную пару ключей. С помощью открытого ключа клиента и собственной пары ключей сервер может сгенерировать общий секрет K.

Хэш обмена и его подпись служат нескольким целям: Затем сервер генерирует нечто, называемое хэшем обмена H, и подписывает его, генерируя подписанный хэш HS (подробнее на рис. 3).

  • Поскольку хэш обмена включает общий секрет, он доказывает, что другая сторона смогла создать общий секрет.
  • Цикл подписи/проверки хэша и подписи обмена позволяет клиенту проверить, что сервер владеет закрытым ключом хоста, и поэтому клиент подключен к правильному серверу (если клиент может доверять соответствующему открытому ключу, подробнее об этом позже).
  • За счёт подписи хэша вместо подписи входных данных, размер подписываемых данных существенно уменьшается и приводит к более быстрому рукопожатию.

Хэш обмена генерируется путём взятия хэша (SHA256, SHA384 или SHA512, в зависимости от алгоритма обмена ключами) следующих полей:

  • Мэджики M. Версия клиента, версия сервера, сообщение клиента SSH_MSG_KEXINIT, сообщение сервера SSH_MSG_KEXINIT.
  • Открытый ключ (или сертификат) хоста сервера HPub. Это значение (и соответствующий ему закрытый ключ HPriv) обычно генерируется во время инициализации процесса, а не для каждого рукопожатия.
  • Клиентский открытый ключ А
  • Серверный открытый ключ B
  • Общий секрет K

С этой информацией сервер может сконструировать сообщение SSH_MSG_KEX_ECDH_REPLY, применив эфемерный открытый ключа сервера B, открытый ключ хоста сервера HPub и подпись на хэше обмена HS. См. рис. 4 для более подробной информации.

2.
Рис. Генерация хэша обмена H

Как только клиент получил от сервера SSH_MSG_KEX_ECDH_REPLY, у него есть всё необходимое для вычисления секрета K и хэша обмена H.

Чтобы предотвратить атаки типа «человек в середине» (MitM), после проверки подписи открытый ключ хоста (или сертификат) проверяется по локальной базе известных хостов; если этот ключ (или сертификат) не является доверенным, соединение разрывается. В последней части обмена ключами клиент извлекает открытый ключ хоста (или сертификат) из SSH_MSG_KEX_ECDH_REPLY и проверяет подпись хэша обмена HS, подтверждающую право собственности на закрытый ключ хоста.

The authenticity of host 10.10.10.10 (10.10.10.10)' can't be established.
ECDSA key fingerprint is SHA256:pnPn3SxExHtVGNdzbV0cRzUrtNhqZv+Pwdq/qGQPZO3.
Are you sure you want to continue connecting (yes/no)?

SSH-клиент предлагает добавить ключ хоста в локальную базу известных хостов. Для OpenSSH это обычно ~/.ssh/known_hosts

Хороший способ избежать таких сообщений — использовать вместо ключей сертификаты SSH (что Teleport делает по умолчанию), которые позволяют вам просто хранить сертификат удостоверяющего центра в локальной базе известных хостов, а затем проверять все хосты, подписанные этим УЦ. Такое сообщение означает, что представленного ключа нет в вашей локальной базе данных известных хостов.

3.
Рис. Генерация ответа при обмене ключами ECDH

Новые ключи

Перед тем, как начать массовое шифрование данных, остался последний нюанс. Обе стороны должны создать шесть ключей: два для шифрования, два вектора инициализации (IV) и два для целостности. Вы можете спросить, зачем так много дополнительных ключей? Разве не достаточно общего секрета K? Нет, не достаточно.

Одна из причин связана с историческим развитием протоколов, таких как TLS и SSH, а именно с согласованием криптографических примитивов. Во-первых, почему нужны отдельные ключи для шифрования, целостности и IV. Но, как верно объясняет Хенрик Хеллстрём, при неправильном выборе примитивов (например, AES-256-CBC для шифрования и и AES-256-CBC-MAC для аутентификации) последствия могут быть катастрофическими. В некоторых выбранных криптографических примитивах повторное использование ключа не представляет проблемы. Следует отметить, что разработчики протоколов постепенно отказываются от такой гибкости, чтобы сделать протоколы более простыми и безопасными.

Далее, зачем используются ключи каждого типа.

Ключи шифрования обеспечивают конфиденциальность данных и применяются с симметричным шифром для шифрования и дешифрования сообщения.

В отсутствие проверки целостности злоумышленник может изменить шифротекст, который передаётся по открытым каналам, и вы расшифруете поддельное сообщение. Ключи целостности обычно используются с кодом проверки подлинности сообщения (MAC), чтобы гарантировать аутентичность шифротекста. Такая схема обычно называется Encrypt-then-MAC.

Следует отметить, что современные шифры AEAD (аутентифицированное шифрование с присоединёнными данными, когда часть сообщения шифруется, часть остаётся открытой, и всё сообщение целиком аутентифицировано) вроде aes128-gcm@openssh.com и chacha20-poly1305@openssh.com фактически не используют производный ключ целостности для MAC, а выполняют аутентификацию внутри своей конструкции.

Их цель состоит в том, чтобы гарантировать, что одно и то же сообщение, зашифрованное дважды, не приведёт к одному и тому же шифротексту. Векторы инициализации (IV) обычно представляют собой случайные числа, используемые в качестве входных данных для симметричного шифра. Необходимость такой процедуры отлично демонстрирует знаменитое изображение с пингвином Туксом, зашифрованное в режиме электронной кодовой книги (ECB).

(1) Открытый текст в виде изображения.
Слева направо. (3) Криптограмма, полученная шифрованием в режиме, отличном от ECB. (2) Криптограмма, полученная шифрованием в режиме ECB. Изображение представляет собой псевдослучайную последовательность пикселей

Использование (и взлом) векторов IV — интересная тема сама по себе, о которой написал Филиппо Вальсорда.

Как отметил Томас Порнин, если используется только один ключ целостности, злоумышленник может воспроизвести клиенту отправленную ему запись, и он будет считать её действительной. Наконец, почему ключи идут в парах? Со спаренными ключами целостности (у сервера и клиента), клиент выполнит проверку целостности шифротекста и такой трюк не сработает.

Теперь с пониманием того, зачем нужны эти ключи, давайте посмотрим, как они генерируются, согласно RFC:

  • Начальный вектор IV от клиента к серверу: HASH(K || H || «A» || session_id)
  • Начальный вектор IV от сервера к клиенту: HASH(K || H || «B» || session_id)
  • Ключ шифрования от клиента к серверу: HASH(K || H || «C» || session_id)
  • Ключ шифрования от сервера к клиенту: HASH(K || H || «D» || session_id)
  • Ключ контроля целостности от клиента к серверу: HASH(K || H || «E» || session_id)
  • Ключ контроля целостности от сервера к клиенту: HASH(K || H || «F» || session_id)

Здесь используется алгоритм хэширования SHA в зависимости от алгоритма обмена ключами, а символ || подразумевает конкатенацию, то есть сцепление.

Как только вычислены эти значения, обе стороны посылают SSH_MSG_NEWKEYS, чтобы сообщить другой стороне, что обмен ключами завершён, а все будущие коммуникации должны происходить с использованием новых ключей, созданных выше.

4:.
Рис. Генерация для других ключей происходит по той же схеме, если заменить A и B на C, D, E и F, соответственно Генерация начального вектора IV.

Заключение

На этом этапе обе стороны согласовали криптографические примитивы, обменялись секретами и сгенерировали материал ключей для выбранных примитивов. Теперь между клиентом и сервером может быть установлен безопасный канал, который обеспечит конфиденциальность и целостность.

Вот как рукопожатие SSH устанавливает безопасное соединение между клиентами и серверами.

Теги
Показать больше

Похожие статьи

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Кнопка «Наверх»
Закрыть