Ресурсы: техническое описание TLS, LaTeX - в картинки (img), криптографическая библиотека Arduino, шифр "Кузнечик" на ассемблере AMD64/AVX и ARM64
Небольшой комментарий о привычных форматах и способах записи TLS-сертификатов (SSL-сертификатов, как почему-то некоторые продолжают называть). Такой сертификат представляет собой публичный электронный документ, состоящий из множества полей. Внутри эти поля записываются в так называемой ASN.1-структуре, которая, в общих чертах, является иерархией вложенных строк байтов. Общий принцип кодирования здесь такой: строка всегда начинается с префикса, точно задающего тип поля данных и длину данных, а оставшиеся байты – несут сами полезные данные. С базовыми, независимыми от платформы, способами записи связаны разные тонкости, исторически сложившиеся “допущения”, а также и всякие прочие спецификации, например, DER (Distinguished Encoding Rules). Однако реальные хитрости и сложности, происходящие из интерпретации упомянутых схем/спецификаций, возникают только у разработчиков программного обеспечения, которое существенным образом использует данные TLS-сертификатов, но не у пользователей. Например, содержимое файла сертификата в удобном формате PEM выглядит, примерно, так (но тут, для удобства, удалена большая часть строк):
-----BEGIN CERTIFICATE----- MIIEDjCCAvagAwIBAgISBB+ebYSbzCVbUmAq3rUH97bcMA0GCSqGSIb3DQEBCwUA MDIxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MQswCQYDVQQD [...] JaRB6DTHZdmM0MzOf6ltVn48cE8LVUuTAM7cFcw+Z1a40XlrMj0nY6Et+QDTZ1n+ 2QZDaj5N+G21wxqvpj29BusHurW0xpFIM/Iv2+A8sX+IWQ== -----END CERTIFICATE-----
Никакой сложности или “криптографии” конкретно тут, в способе записи сертификата, нет. Если не использовать нарочито строгие формулировки, то PEM – это просто текстовый формат с base64-кодированием, переводами строк на заданной границе и строками-разделителями, которые определяются пятью символами “минус” с BEGIN/END. В данном случае:
"-----BEGIN CERTIFICATE-----"
и
"-----END CERTIFICATE-----".
Между этими строками находится просто base64-запись байтов сертификата, закодированного в DER (можно считать, что в “бинарном” виде, а не в “тексте”). Если взять байты сертификата, закодировать их в base64, поместить результат в текстовый редактор, дописать “BEGIN…END” в заданном формате с минусами, добавить переносы строк, то получится PEM. И наоборот. (Исключения, наверное, можно попробовать придумать, но они будут экзотическими.) Естественно, так как сертификат содержит внутри электронную подпись, то значения всех его битов – важны: если что-то изменится, то подпись перестанет сходиться (или вообще проверяться, если испорчена сама запись подписи).
Преобразовать сертификат между текстовым PEM и “бинарным” DER можно при помощи OpenSSL:
PEM -> DER $ openssl x509 -in cert.pem -out cert.der -outform DER DER -> PEM $ openssl x509 -in cert.der -out cert.pem -inform DER -outform PEM
(Опция “-inform DER” во втором случае нужна потому, что openssl x509 по умолчанию ожидает формат PEM.)
В сертификате при этом ничего не изменяется, никаких особо сложных операций не выполняется, а OpenSSL здесь нужен только как удобная утилита “всё в одном”. Аналогичного эффекта, действуя через командную строку, нетрудно добиться и сочетанием cat с base64 -d.
Комментировать »
Надо сказать, я несколько лет назад отмечал, что интересно будет посмотреть, внедрит ли Google поддержку ESNI в свой браузер. Интерес, на мой взгляд, тут происходил из того, что Google последовательно отказывался поддерживать такие технологии обеспечения безопасности, которые использовали тот или иной независимый инструмент управления криптографическими ключами в TLS. Примеров два: изгнание из веба DANE (отпечатки ключей/сертификатов в DNS, для сверки с предъявляемыми сервером) под предлогом замены на Certificate Transparency (которая хоть и полезная, но о другом, так как не может предотвратить использование валидного подменного сертификата в момент соединения); отключение HPKP (запоминание отпечатков серверных ключей клиентом, как в SSH).
И вот я предположил, что, вероятно, ESNI тоже не будет в Google Chrome. Но сейчас вышло иначе: вместо исходного варианта ESNI – Google Chrome (Chromium) всё же поддержал ECH, а это развитие ESNI, гораздо более продвинутое. Впрочем, думаю, что в этой “продвинутости” и состоит причина поддержки: всё же, ECH далеко ушла от первоначальной идеи ESNI – позволяет реализовать доступ к скрытым сервисам, при этом наследует доверие системе хорошо известных удостоверяющих центров (“имени CA/B-форума”); впрочем, ECH и ключи для дополнительной защиты внутри TLS позволяет публиковать, например, в DNS, то есть, не централизованным способом, который, формально, не зависит от браузера (но нельзя забывать о встроенной поддержке DNS-over-HTTPS с заданными провайдерами). В общем, поддержка внешних ключей появилась, но теперь нужно посмотреть, как будет она развиваться: ведь доверенные ключи для ECH могут приезжать и вместе с браузером – это важная особенность.
Комментарии (2) »
В атаке с перехватом трафика Jabber.ru использовался активный сетевой прокси с MITM. Однако если процесс, реализующий TLS, исполняется в виртуальной машине, а гипервизор контролируется провайдером хостинга, то можно проводить полностью пассивную атаку с рашифрованием TLS-трафика, да так, что из виртуальной машины атаку видно не будет. Это существенно сложнее прокси, терминирующего TLS с подменным сертификатом, и ограничивает возможности по расширению атаки до активной (с вмешательством в трафик), но является куда как более изящным методом. Для реализации требуется доступ к функции копирования (“дампа”) памяти гипервизора, а кроме того, естественно, доступ к сетевому трафику виртуальной машины (либо тоже на уровне “виртуализации” гипервизора, либо на уровне “внешней” сети).
Основная идея такая: общий сессионный секрет и сеансовые ключи TLS-соединения находятся в оперативной памяти виртуальной машины – нужно их из памяти извлечь, выполнив выгрузку копии памяти гипервизором в подходящий момент. Самое занятное, что это же относится и к секретному серверному ключу сертификата, который, впрочем, во многих случаях ещё и просто лежит в статическом файле на диске, в открытом виде. Извлечение и использование серверного ключа из файловой системы, при доступе к гипервизору, вообще представляет тривиальную задачу и тут не рассматривается. Варианты с зашифрованным файлом, с зашифрованным томом (диском) – уже сложнее, но тоже реализуемы; так или иначе – это не относится к анализу TLS. А вот извлечение разнообразных ключей из дампа оперативной памяти – относится, поэтому рассмотрим метод в общих чертах, за вычетом возможных мер по маскированию ключей в памяти (см. ниже).
В TLS набор симметричных сеансовых ключей используется сторонами для зашифрования/расшифрования и вычисления кодов аутентификации, поэтому знание ключей позволяет расшифровать TLS-сообщения и подделать TLS-сообщения. Для получения действующих сеансовых ключей используется некоторый общий сессионный секрет, согласованный в начале TLS-сессии. Этот секрет позволяет простым способом вычислить сами сеансовые ключи (обратное – не верно), поэтому достаточно найти сессионный секрет. В TLS 1.3 процесс работы с исходными секретами разбит на шаги, каждый из которых выводит симметричные ключи для соответствующего этапа соединения, так что ситуация несколько сложнее, но эти детали тоже пропустим.
Чтобы зафиксировать нужные симметричные ключи в памяти виртуальной машины, нужно определить момент, когда они там образуются. Если момент упустить, то сеансовые ключи могут быстро потеряться, так как соответствующие байты в памяти окажутся перезаписаны. Для фиксирования удобного момента требуется наблюдение над сетевым трафиком: по статусу TLS-соединения можно определить, что приложение должно вычислить ключи, и в этот момент сделать дамп памяти (или несколько последовательных дампов). Ход сетевого трафика, при необходимости, можно и “подвесить”, так как речь всё же идёт про ситуацию контроля над гипервизором. После того, как дамп памяти снят, данные из него анализируются с целью извлечения ключей, а TLS-трафик пассивно записывается.
Как найти ключи в дампе памяти? Есть прямой, но не самый быстрый, способ полного перебора: пробное расшифрование (или вычисление кода аутентификации) выполняется по порядку для каждой байтовой последовательности дампа нужной длины. Возможны, конечно, варианты, когда значение ключа оказалось в дампе памяти разрезано на части, поэтому такой перебор не сработает. Более точные результаты даст предварительная разметка областей по признаку записи, а также анализ логических блоков по схеме представления памяти в гостевой ОС. Понятно, что это всё можно сделать на уровне гипервизора. Для чего-то даже имеются готовые инструменты, что-то придётся запрограммировать. Схема с перебором работает и для секретного серверного ключа, только вместо пробного расшифрования нужно выполнять другую операцию (например, для ECDSA – пробное умножение; но это детали, главное, что в TLS-трафике всегда есть опорные метки).
Ключи и секрет могут быть замаскированы в памяти приложением (обычно, XOR с псевдослучайной маской, маска хранится отдельно или вычисляется по необходимости специальной функцией). Такое решение встречается нередко. Однако для того, чтобы ключи использовать – их всё же придётся раскрыть для операций хеш-функций и шифров, поэтому достаточно угадать момент выполнения дампа памяти. (Можно предложить алгоритмы с дополнительным непрерывным перемешиванием адресации и масок на уровне реализации шифров/хеш-функций, но вряд ли такое где-то встречается на практике.)
Проблемы с данным методом могут начаться тогда, когда параллельных TLS-соединений очень много: с одной стороны, возрастают шансы поймать много ключей в дампах памяти, с другой – дополнительные сложности с отслеживанием и сопоставлением состояний.
Перевод атаки в активную возможен, если не возникло существенного рассогласования по времени между моментом определения ключей и TLS-сессией. Так как атакующей стороне известны секретные симметричные ключи, она может подготовить корректную TLS-запись (или несколько записей) с нужными данными и встроить их в трафик, перехватив какие-то элементы протокола, работающего внутри TLS – но тут необходимо учитывать, что разойдутся счётчики и последовательность записей, так что подлинная сессия, вообще говоря, развалится, однако можно её до какой-то степени продолжать подменным узлом.
Схема работает не только для TLS, но и для других протоколов (SSH, например), если только реализации не подразумевают достаточно сложных механизмов защиты ключей. При этом понятно, что никакой “полной защиты” от гипервизора тут быть не может.
Комментарии (3) »
В свете нашумевшей атаки на Jabber.ru (с перехватом TLS) нередко пишут, будто эта атака показала, что “система хорошо известных (публичных) удостоверяющих центров TLS не вызывает доверия”. Атака, конечно, такое показала, но с уточнениями: “система хорошо известных УЦ” и раньше должна бы “вызывать доверие” равно в пределах разумной модели угроз, то есть – доверять ей можно только в сугубо определённых, узких случаях. И нельзя расширительно толковать возможности УЦ – это как раз большая ошибка, но весьма распространённая. В случае же инцидента с Jabber.ru, если говорить о сторонах, которые “вызывают доверие”, то тут такой стороной должен быть прежде всего хостер – предполагается высокая степень доверия хостеру (но не полное доверие, даже в этом случае), а только потом – немного доверия УЦ.
Комментарии (4) »
Пишут про перехват TLS-трафика сервиса Jabber.ru, без ведома администраторов: это практическая атака, судя по подробному описанию – там всё как положено: MITM в TLS и подмена серверного сертификата на тоже валидный. Как пишут, выпуск сертификата, скорее всего, проведён при помощи перехвата трафика, идущего на оригинальный сервер – подменные сертификаты попали в CT-логи, в описании есть на них ссылки (это сертификаты Let’s Encrypt, конечно).
Вообще, побороться с подобной подменой, когда возможен перехват трафика на уровне хостера (а это практически всегда так), весьма сложно. Единственный более или менее эффективный способ – прямая авторизация серверных ключей клиентом по отпечаткам, однако, это сложно, плохо масштабируется, ну и так далее. (Отмечу, что применительно к Jabber/XMPP – есть схемы с защитой точка-точка, между пользователями – OMEMO, например). Certificate Transparency (CT), CAA и подобные технологии, направленные на УЦ, от таких атак не особо защищают: CT, несомненно, полезно, но часто работает постфактум, потому что, как минимум, нужно клиентам проверять метки в сертификатах; и это, если вообще считать, что CT тут работает – технически, выпустить быстрый подменный сертификат УЦ может без меток логов, ничто этому не мешает; да и метки можно сделать без публикации в логах, если есть ключи от этих логов; но, конечно, это всё существенно усложняет процесс. Что касается CAA-записей: да, это полезно, но для УЦ, технически, отказаться от проверки CAA ещё проще, чем проигнорировать CT-логи и SCT-метки.
(Ссылка: описание инцидента от OpenNet на русском.)
Дополнение: понятно, что УЦ, в такой конфигурации атаки, ни при чём – УЦ не имеет возможности в рамках сетевых протоколов отличить подменный узел от настоящего с точностью, превышающей перенаправление сетевого трафика в локальной сети хостера; естественно, автоматически выпускаемые TLS-сертификаты для веба не могут служить инструментом защиты от подобных атак, это и не планировалось, никакие CT тут не помогут; возможность активного и полного перехвата трафика с подменой – автоматически приводит к возможности выпустить TLS-сертификат с соответствующим именем хоста через УЦ TLS; перехват трафика – позволяет подменить данные и при DNS-проверке, это даже в чём-то проще, но перехватывать нужно трафик к DNS-серверам и/или от них (и не должно быть поддержки DNSSEC, да).
Комментарии (4) »
Продолжаем небольшую серию записок про TLS-сервер на tls13.1d.pw. Этот сервер передаёт несколько сертификатов, в том числе и один необычный сертификат, увидеть который можно только в выдаче той или иной специальной утилиты (например, s_client из OpenSSL) или упомянутым сервисом SSLLabs. Этот сертификат сервер генерирует (и даже подписывает, но это тут не важно) в самом начале установления соединения, а в поля Subject и Issuer записываются, соответственно, IP-адрес с номером порта клиента и имя выбранной криптосистемы обмена ключами. Это такой экзотический способ “посигналить” в (закрытой) части TLS-сообщений. Клиенты должны бы игнорировать неподходящий сертификат в процессе валидации (но могут и ошибку выдать, конечно).
Комментировать »
В продолжение недавней записки про X25519Kyber768 на TLS-сервере – подробности встраивания данной гибридной криптосистемы в схему работы TLS 1.3.
(Дополнение, 17/12/2024: в 2024 году Kyber768 была стандартизована NIST под обозначением ML-KEM; ML-KEM, как алгоритм, имеет некоторые отличия от Kyber768, поэтому две криптосистемы, хоть и совпадают по математической основе, но не совместимы на уровне операций. Браузеры, чтобы не поддерживать несколько максимально похожих криптосистем, использование которых сопряжено с передачей больших блоков данных, перешли с Kyber768 на ML-KEM, но тоже в составе “гибрида” X25519 + ML-KEM. Способ встраивания ML-KEM логически полностью совпадает с описанным ниже для Kyber768, отличается только порядок блоков данных.)
1. Как нетрудно догадаться, X25519Kyber768 состоит из X25519 и Kyber768, поэтому криптосистема и гибридная. X25519 – это хорошо известный вариант протокола Диффи-Хеллмана (DH), здесь используется без изменений, обычным образом (см. кстати, заметку с задачей про 2^255 – 19). Kyber768 – схема KEM (инкапсуляции ключа), построенная на криптосистеме Kyber с “постквантовой стойкостью”. Эта криптосистема реализует зашифрование с открытым ключом (важный момент).
2. В TLS рассматриваемая криптосистема используется для получения симметричного сеансового секрета. Открытый ключ передаётся клиентом в составе ClientHello, в расширении key_share, а ответная часть сервером – в ServerHello, key_share. В логике сообщений тут ничего не меняется.
3. Изменяется часть внутри key_share, соответствующая X25519Kyber768 – клиент передаёт результат конкатенации байтов, составляющих клиентскую часть DH X25519 и открытый ключ клиента Kyber768. Эти данные имеют фиксированную длину, определяемую алгоритмами: 32 начальных байта для X25519 и 1184 для Kyber768, 1216 байтов всего. На сервере данные разделяются (просто, по длине) и используются для обеих криптосистем. А именно: для X25519 сервер вычисляет общий секрет DH и серверную открытую часть DH (B), так же, как это делалось бы в случае отдельной криптосистемы X25519; для Kyber768 – сервер генерирует общий секрет и оборачивает его в KEM (то есть, зашифровывает исходное секретное значение, используя открытый ключ Kyber, присланный клиентом – тем самые 1184 байта). Два секрета сервер объединяет в один массив – здесь, опять же, простая конкатенация: BaseSecret = x25519[] + Kyber_Shared_Secret[]. Обратите внимание на важное техническое отличие: для X25519 общий секрет, на сервере, это результат умножения открытой части DH клиента (A) на секретный скаляр сервера d: s = d*A; а для Kyber – сервер выбирает исходное значение, которое отправляет клиенту в зашифрованном виде (очень похоже на устаревшую схему с RSA-шифрованием в TLS, но устроенную наоборот). При этом внутри KEM Kyber для вычисления секрета по исходному значению используется отдельная функция (KDF), подмешивающая ещё и значение открытого ключа, это необходимый шаг, но, с точки зрения логики получения секрета, это не так важно. Секрет, генерируемый в рамках Kyber768 в TLS – это тоже 32 байта (256 бит). После завершения данного этапа – сервер получил общий симметричный секрет, представляющий собой объединение выдачи двух алгоритмов: 32 байта и 32 байта. Также сервер получил открытую часть DH и зашифрованный Kyber симметричный секрет (это только часть, предназначенная для Kyber, результат X25519 сюда не попадает).
4. Сервер формирует ответное расширение key_share, присоединяя к 32 байтам открытой части DH X25519 байты шифротекста с симметричным секретом, который зашифрован Kyber – длина шифротекста 1088 байтов, всего 1120 байтов. Ответное key_share сервер отправляет клиенту в открытой части сообщений, в ServerHello, после чего генерирует на основе общего секрета набор симметричных сессионных ключей и переходит к зашифрованному обмену данными.
5. Клиент, получив key_share X25519Kyber768, разделяет данные на открытую часть обмена DH X25519 (B) и шифротекст Kyber768. По значению B DH клиент вычисляет общий секрет DH X25519 (здесь – 32 байта), который совпадает с серверным. Используя секретный ключ, клиент расшифровывает шифротекст и вычисляет общий секрет Kyber. Оба полученных значения объединяются, результат должен совпасть с серверным. (Тут слово “должен” использовано потому, что в Kyber, к сожалению, есть вероятностный элемент: так как это схема, концептуально происходящая из кодов с коррекцией ошибок, то имеется очень небольшая вероятность, что “ошибка” всё же останется, а клиент и сервер получат разные значения секрета.) На основе объединённого секрета клиент вычисляет набор симметричных ключей и может проверить подлинность и расшифровать следующие сообщения сервера.
Таким образом, Kyber простым и понятным способом добавляет 256 бит “постквантовой стойкости” к исходному симметричному секрету TLS-сессии, какие-то другие параметры – не изменяются.
Комментировать »
Кстати, индекс 0x6399, который позволяет отличить ключи криптосистемы X25519Kyber768Draft00 в TLS-сообщениях, внесён в соответствующий реестр номеров IANA, в раздел под именем TLS Supported Groups. Название раздела – ещё один пример исторически сложившихся особенностей спецификаций: понятно, что X25519Kyber768 – никакая ни группа, а сразу две криптосистемы, построенные на различном математическом аппарате (но, естественно, группы нетрудно найти и в X25519, и в Kyber768). Изначально, упомянутый раздел параметров TLS содержал индексы именованных эллиптических кривых, то есть, сочетаний из параметров, определяющих конкретную кривую в прикладном смысле. Но так как для криптосистем существенны были именно операции в группе, а кроме эллиптических кривых ещё использовались (и используются) мультипликативные группы колец вычетов, то раздел, довольно давно, переименовали в “Поддерживаемые группы”, теперь туда записывают наборы криптосистем.
Комментировать »
Всё же я пока восстановил свой экспериментальный сервер TLS 1.3 – tls13.1d.pw (некоторое время назад я писал, что собираюсь его совсем отключить). А чтобы восстановление выглядело поинтереснее, я реализовал на сервере поддержку постквантовой схемы получения общего секрета (KEM) X25519Kyber768. TLS с Kyber768 там реализован вручную, но я, впрочем, использовал криптопримитивы из удобной библиотеки Cloudflare.
Криптосистему с постквантовой схемой KEM Kyber768 в конце августа Google внедрил в браузер Chrome (в порядке эксперимента), так что можете проверить – на сервере у X25519Kyber768 повышен приоритет, поэтому, при наличии соответствующего открытого ключа в сообщении клиента, выбираться она должна довольно часто.
Вообще, открытый блок клиентского KeyShare в X25519Kyber768 весит аж 1216 байтов (32 + 1184, потому что это ключ X25519, 32 байта, плюс ключ постквантовой части Kyber768, который большой). Тем не менее, я всё же пока что сделал вывод этого ключа без сокращений, что, возможно, выглядит тяжеловато, но видно будет только в браузере с поддержкой данной криптосистемы. (Дополнение, 12/09/2023: технические подробности об использовании криптосистемы.)
Поддержка есть только в самых свежих версиях Chrome (>=116), а включать её нужно через флаги: chrome://flags, набрать “TLS13” в поиске, флаг называется “TLS 1.3 hybridized Kyber support”.

(Не знаю, будет ли у меня возможность поддерживать сервер далее, так что в какой-то момент он может отключиться, теперь уже даже и без предупреждения, но посмотрим; ошибки подключения, естественно, могут быть и по другим причинам – это, всё ж, экспериментальный сервер.)
Комментировать »
В Chrome свежих версий добавлена экспериментальная поддержка “постквантового алгоритма” получения общего симметричного секрета для TLS 1.3 – X25519Kyber768. Это гибридный вариант, в котором в дополнение к “обычной” схеме X25519 используется криптосистема Kyber с заявленной высокой стойкостью ко взлому на гипотетическом универсальным квантовом компьютере (естественно, в дополнение к классической стойкости).
Технически это работает следующим образом: при установлении TLS-соединения Chrome добавляет в начальное сообщение ClientHello клиентскую часть данных X25519Kyber768 (и, естественно, индекс данной криптосистемы указывается в перечне поддерживаемых), если TLS-сервер может использовать данную криптосистему, то он выбирает соответствующий ключ из ClientHello, вычисляет симметричный секрет и использует его на дальнейших этапах. Это работает для TLS 1.3, при этом никак не изменяет каких-то других аспектов процесса установления соединения – не влияет на сертификаты и ключи к ним, не меняет шифров и т.д. На серверной стороне – обещают поддержку от Cloudflare и на некоторых узлах Google. Не вдаваясь в детали, можно смело считать, что X25519Kyber768 – это просто присоединение байтов секрета, полученного Kyber768, к байтам секрета, полученного X25519, на входе функции вычисления ключей для симметричного шифра, в полном соответствии с имеющейся схемой преобразования симметричных ключей TLS 1.3. То есть, схема, как минимум, не хуже криптосистемы X25519, которая уже давно используется, но не обладает постквантовой стойкостью (поскольку это вариант протокола Диффи-Хеллмана с логарифмированием в группе точек эллиптической кривой).
Насколько близки квантовые компьютеры, позволяющие быстро решать задачи отыскания соответствующих секретов асимметричных криптосистем, пока что не очень понятно. Однако постквантовые криптосистемы внедряются из предположения, что такой компьютер всё же может быть создан и позволит расшифровать ранее записанный трафик, из этого делается логичный вывод, что защиту нужно начинать внедрять заранее. Кстати, тут возникает не менее логичный вопрос: почему данный подход не применялся к разнотипным криптосистемам в том же TLS ранее, без требований о квантовых компьютерах? Например, можно же взять какую-нибудь экзотическую криптосистему и прикрепить её к распространённой реализации классического протокола Диффи-Хеллмана (DH), чтобы, если через двадцать лет будет найден неквантовый метод эффективного взлома классического DH, записанный трафик всё ещё оказался бы защищён (улучшения вычислительных атак на классический (“мультипликативный”) DH есть весьма существенные). Вопрос интересный, да. С одной стороны, задачи, на которых строятся распространённые сейчас асимметричные криптосистемы, нередко имеют математически эквивалентную структуру, с точки зрения сложности: то есть, одну задачу можно перевести в другую “с точностью до некоторой константы” (но тут есть куча оговорок – иногда “константа” получается слишком большой, например). С другой стороны, использование отдельного симметричного секрета, распределяемого по защищённому каналу, возможно и в TLS (называется PSK – Pre-Shared Key).
Комментировать »
Что касается STARTTLS. Для доставки электронной почты между почтовыми серверами в Интернете повсеместно используется протокол SMTP. SMTP – это “текстовый протокол”, то есть, его работа основана на командах, отправляемых в виде человекопонятного текста (ну, с точностью до числовых кодов состояний, которые, впрочем, тут тоже записываются ASCII-текстом) через любой подходящий транспорт. Многие достаточно древние протоколы в Интернете – текстовые. Потому что текстовые протоколы – это очень удобно и понятно. Там, где применимо. Сейчас, постепенно, этот подход возвращается (примеры: текстовые, REST-подобные API с JSON и др.), но, конечно, не везде.
Вернёмся к SMTP. Классические SMTP-сессии проходят в открытом виде, это означает, что содержание письма, доставленного электронной почтой, будет нетрудно просмотреть на любом промежуточном узле, которых легко могут быть десятки. (Обратите внимание, что дополнительные методы зашифрования содержания письма – PGP, S/MIME и т.д. – они относятся к другому уровню, не к SMTP.) Чтобы иметь возможность дополнительно защитить содержание писем в процессе доставки и используется STARTTLS: этот механизм позволяет SMTP-клиенту и SMTP-серверу перейти на защищённый канал “точка-точка” (см. пояснение ниже) после того, как они уже начали сессию в открытом варианте.
Для перехода к TLS, если сервер поддерживает STARTTLS, клиент просто отправляет команду STARTTLS (в виде текстовой строки, в открытом виде). Если сервер подтверждает, что готов к TLS, клиент в этом же “транспортном” сокете отправляет начальный пакет TLS-соединения (ClientHello, начинает “хендшейк”), после чего стороны могут согласовать защищённый сокет. Далее, если процесс установления TLS-соединения успешно завершился, SMTP-сессия начинается, фактически, заново, в текстовом формате, но уже внутри защищённого TLS транспорта. То есть, на логику SMTP использование STARTTLS влияет минимальным образом.
Оговорка об уровне “точка-точка”: естественно, под “точка-точка” тут подразумевается соединение между конкретным клиентом SMTP и конкретным сервером, но не далее. Доставка почты так устроена, что почтовые серверы (“релеи”) часто используются цепочкой, поэтому конкретное письмо может проходить через несколько почтовых серверов (не следует путать с промежуточными узлами уровня IP и ниже – здесь речь про уровень SMTP, там тоже есть пересылающие серверы). Так что использование TLS-соединения на каком-то этапе (“звене”) доставки сообщений не означает, что данное письмо поедет через TLS и дальше.
Поскольку сам SMTP полностью открыт, его не так уж трудно проксировать с изменениями, даже подменяя IP-адреса узлов. Серверное сообщение о поддержке STARTTLS можно просто вырезать из соответствующего ответа – если клиент допускает доставку без TLS, то он уже не будет пытаться установить TLS-соединение, а перейдёт к доставке в открытом виде. Это давно известная особенность, указанная в RFC.
В практике SMTP, при доставке писем между почтовыми серверами, принято не особенно строго подходить к обработке параметров TLS. Причина в том, что иначе почта перестанет ходить совсем. Поэтому TLS тут является примером того, что называется “приспособительным” (или “ситуативным”) подходом в использовании криптографии для защиты от прослушивания: “если удалось, то будем зашифровывать, а если нет – тогда ладно”. (В английском варианте – “opportunistic encryption”; однако переводить тут opportunistic на русский как “оппортунистическое” – не верно: соответствующие коннотации слишком сильно отличаются; это даже хуже, чем Чарльз, превращающийся в Карла.) Для защищённой работы SMTP есть и вариант использовать TLS-соединение сразу, до начала SMTP-сессии (SMTPS и др.), однако этот подход уже не имеет отношения к STARTTLS.
Комментировать »
Новый