- PVSM.RU - https://www.pvsm.ru -
Secure Shell (SSH) — широко используемый протокол транспортного уровня для защиты соединений между клиентами и серверами. Это базовый протокол в нашей программе Teleport [1] для защищённого доступа к инфраструктуре. Ниже относительно краткое описание рукопожатия, которое происходит перед установлением безопасного канала между клиентом и сервером и перед началом полного шифрования трафика.
Рукопожатие начинается с того, что обе стороны посылают друг другу строку с номером версии. В этой части рукопожатия не происходит ничего чрезвычайно захватывающего, но следует отметить, что большинство относительно современных клиентов и серверов поддерживают только SSH 2.0 из-за недостатков в дизайне версии 1.0.
В процессе обмена ключами (иногда называемого KEX) стороны обмениваются общедоступной информацией и выводят секрет, совместно используемый клиентом и сервером. Этот секрет невозможно обнаружить или получить из общедоступной информации.
Обмен ключами начинается с того, что обе стороны посылают друг другу сообщение SSH_MSG_KEX_INIT со списком поддерживаемых криптографических примитивов и их предпочтительным порядком.
Криптографические примитивы должны установить строительные блоки, которые будут использоваться для обмена ключами, а затем полного шифрования данных. В таблице ниже перечислены криптографические примитивы, которые поддерживает Teleport.
| Обмен ключами (KEX) | Симметричный шифр | Код аутентификации сообщения (MAC) | Алгоритм ключа хоста сервера |
|---|---|---|---|
| curve25519-sha256@libssh.org | chacha20-poly1305@openssh.com | hmac-sha2-256-etm@openssh.com | ssh-rsa-cert-v01@openssh.com |
| ecdh-sha2-nistp256 | aes128-gcm@openssh.com | hmac-sha2-256 | ssh-rsa |
| ecdh-sha2-nistp384 | aes256-ctr | ||
| ecdh-sha2-nistp521 | aes192-ctr | ||
| aes128-ctr |
Криптографические примитивы 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 для более подробной информации.
[3]
Рис. 2. Генерация хэша обмена H
Как только клиент получил от сервера SSH_MSG_KEX_ECDH_REPLY, у него есть всё необходимое для вычисления секрета K и хэша обмена H.
В последней части обмена ключами клиент извлекает открытый ключ хоста (или сертификат) из SSH_MSG_KEX_ECDH_REPLY и проверяет подпись хэша обмена HS, подтверждающую право собственности на закрытый ключ хоста. Чтобы предотвратить атаки типа «человек в середине» (MitM), после проверки подписи открытый ключ хоста (или сертификат) проверяется по локальной базе известных хостов; если этот ключ (или сертификат) не является доверенным, соединение разрывается.
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 делает по умолчанию), которые позволяют вам просто хранить сертификат удостоверяющего центра в локальной базе известных хостов, а затем проверять все хосты, подписанные этим УЦ.
[4]
Рис. 3. Генерация ответа при обмене ключами ECDH
Перед тем, как начать массовое шифрование данных, остался последний нюанс. Обе стороны должны создать шесть ключей: два для шифрования, два вектора инициализации (IV) и два для целостности. Вы можете спросить, зачем так много дополнительных ключей? Разве не достаточно общего секрета K? Нет, не достаточно.
Во-первых, почему нужны отдельные ключи для шифрования, целостности и IV. Одна из причин связана с историческим развитием протоколов, таких как TLS и SSH, а именно с согласованием криптографических примитивов. В некоторых выбранных криптографических примитивах повторное использование ключа не представляет проблемы. Но, как верно объясняет Хенрик Хеллстрём [5], при неправильном выборе примитивов (например, AES-256-CBC для шифрования и и AES-256-CBC-MAC для аутентификации) последствия могут быть катастрофическими. Следует отметить, что разработчики протоколов постепенно отказываются от такой гибкости, чтобы сделать протоколы более простыми и безопасными.
Далее, зачем используются ключи каждого типа.
Ключи шифрования обеспечивают конфиденциальность данных и применяются с симметричным шифром для шифрования и дешифрования сообщения.
Ключи целостности обычно используются с кодом проверки подлинности сообщения (MAC), чтобы гарантировать аутентичность шифротекста. В отсутствие проверки целостности злоумышленник может изменить шифротекст, который передаётся по открытым каналам, и вы расшифруете поддельное сообщение. Такая схема обычно называется Encrypt-then-MAC [6].
Следует отметить, что современные шифры AEAD [7] (аутентифицированное шифрование с присоединёнными данными, когда часть сообщения шифруется, часть остаётся открытой, и всё сообщение целиком аутентифицировано) вроде aes128-gcm@openssh.com и chacha20-poly1305@openssh.com фактически не используют производный ключ целостности для MAC, а выполняют аутентификацию внутри своей конструкции.
Векторы инициализации (IV) обычно представляют собой случайные числа, используемые в качестве входных данных для симметричного шифра. Их цель состоит в том, чтобы гарантировать, что одно и то же сообщение, зашифрованное дважды, не приведёт к одному и тому же шифротексту. Необходимость такой процедуры отлично демонстрирует знаменитое изображение [8] с пингвином Туксом, зашифрованное в режиме электронной кодовой книги (ECB).

Слева направо. (1) Открытый текст в виде изображения. (2) Криптограмма, полученная шифрованием в режиме ECB. (3) Криптограмма, полученная шифрованием в режиме, отличном от ECB. Изображение представляет собой псевдослучайную последовательность пикселей
Использование (и взлом) векторов IV — интересная тема сама по себе, о которой написал Филиппо Вальсорда [9].
Наконец, почему ключи идут в парах? Как отметил Томас Порнин [10], если используется только один ключ целостности, злоумышленник может воспроизвести клиенту отправленную ему запись, и он будет считать её действительной. Со спаренными ключами целостности (у сервера и клиента), клиент выполнит проверку целостности шифротекста и такой трюк не сработает.
Теперь с пониманием того, зачем нужны эти ключи, давайте посмотрим, как они генерируются, согласно RFC [11]:
- Начальный вектор 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{256, 384 или 512} в зависимости от алгоритма обмена ключами, а символ || подразумевает конкатенацию, то есть сцепление.
Как только вычислены эти значения, обе стороны посылают SSH_MSG_NEWKEYS, чтобы сообщить другой стороне, что обмен ключами завершён, а все будущие коммуникации должны происходить с использованием новых ключей, созданных выше.
[12]
Рис. 4:. Генерация начального вектора IV. Генерация для других ключей происходит по той же схеме, если заменить A и B на C, D, E и F, соответственно
На этом этапе обе стороны согласовали криптографические примитивы, обменялись секретами и сгенерировали материал ключей для выбранных примитивов. Теперь между клиентом и сервером может быть установлен безопасный канал, который обеспечит конфиденциальность и целостность.
Вот как рукопожатие SSH устанавливает безопасное соединение между клиентами и серверами.
Автор: Дата-центр "Миран"
Источник [13]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/ssh/335698
Ссылки в тексте:
[1] Teleport: https://gravitational.com/teleport
[2] Мэджики: https://github.com/golang/crypto/blob/a49355c7e3f8fe157a85be2f77e6e269a0f89602/ssh/kex.go#L53-L58
[3] Image: https://habrastorage.org/webt/v1/df/pr/v1dfprnrhjw01tlsqn4u148cgqc.png
[4] Image: https://habrastorage.org/webt/xh/jg/zo/xhjgzo174zrxjc-grwuerapldsc.png
[5] объясняет Хенрик Хеллстрём: https://crypto.stackexchange.com/questions/8081/using-the-same-secret-key-for-encryption-and-authentication-in-a-encrypt-then-ma
[6] Encrypt-then-MAC: https://crypto.stackexchange.com/questions/202/should-we-mac-then-encrypt-or-encrypt-then-mac
[7] шифры AEAD: https://en.wikipedia.org/wiki/Authenticated_encryption
[8] знаменитое изображение: https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Electronic_Codebook_(ECB)
[9] написал Филиппо Вальсорда: https://blog.cloudflare.com/tls-nonce-nse/
[10] Томас Порнин: https://crypto.stackexchange.com/questions/1139/what-is-the-purpose-of-four-different-secrets-shared-by-client-and-server-in-ssl
[11] согласно RFC: https://tools.ietf.org/html/rfc4253#section-7.2
[12] Image: https://habrastorage.org/webt/lx/gn/71/lxgn71y33ihsymnavtekvnhw2l4.png
[13] Источник: https://habr.com/ru/post/474654/?utm_source=habrahabr&utm_medium=rss&utm_campaign=474654
Нажмите здесь для печати.