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

TLS (Transport Layer Security) предназначен для создания защищённых каналов обмена информацией. Спецификации определяют несколько версий TLS: 1.0, 1.1, 1.2, 1.3. Версия 1.3 является самой современной, допускается использование версии 1.2, а более старые версии – не рекомендованы.

1.

Один из распространённых сценариев использования TLS – обращение к веб-серверу браузером, то есть “доступ по HTTPS”. TLS применяется для защиты большого количества различных сервисов и протоколов. Примеры, помимо HTTPS: подключения VPN, защищённый доступ к DNS, каналы для управления прикладным ПО, системы обмена сообщениями (мессенджеры) и т.д. TLS в HTTPS и, например, в VPN – это один и тот же протокол. Так, при использовании в HTTPS, роль TLS состоит в создании защищённого канала, через который передаются HTTP-запросы (это такие же запросы, какие передавались бы в открытом виде). Аналогично для VPN – TLS служит защищённым транспортом для сетевых соединений.

Есть немало практических ситуаций, когда реализация TLS логически полностью отделяется от реализации того или иного сервиса, что позволяет защитить трафик “прозрачно”, то есть, без внесения изменений в реализацию самого сервиса. Пример – использование пакета stunnel для защиты DNS-трафика: stunnel настраивается в качестве TLS-сервера, который принимает трафик на выделенном номере порта (853) по TLS, “раскрывает” этот трафик и проксирует, в открытом виде, в сторону обычного DNS-сервера, который может работать на той же машине, но на другом номере порта. Таким способом можно добавить поддержку TLS для DNS-сервера, который сам по себе TLS не поддерживает. Этот подход в более общем случае называют “TLS-терминирование” (см. ниже).

2.

TLS использует парадигму “клиент-сервер” и работает поверх TCP. Клиентом в TLS является сторона, инициирующая защищённое соединение. В штатном случае, клиент в TLS совпадает с клиентом в соответствующем TСP-соединении.

TLS позволяет аутентифицировать узлы при помощи TLS-сертификатов. Возможно придумать другие, экзотические способы аутентификации для TLS, однако только TLS-сертификаты предоставляют универсальный, описанный в спецификации, способ, поэтому используются практически повсеместно. TLS-сертификат – это публичный электронный документ (можно считать, что файл специального формата, который описан в стандарте X.509), позволяющий при помощи электронной подписи привязать открытый криптографический ключ к сетевому имени (или, реже, к сетевому адресу). Сертификаты, идентичные по формату применяемым в TLS, используются во многих других случаях, к TLS отношения не имеющих: например, для публикации ключей в электронном документообороте. TLS-сертификаты являются “X.509-сертификатами”, то есть, их можно так называть. TLS-сертификат не содержит никакой секретной информации (по определению), поэтому не требует защиты при хранении или публикации.

Сертификаты в TLS бывают серверные (их называют “оконечными”), промежуточные и корневые. Фундаментальное отличие серверного сертификата от промежуточного и корневого в том, что серверный сертификат не может быть использован для выпуска других доверенных сертификатов, то есть, он является конечным сертификатом в “цепочке доверия” (откуда и название “оконечный”). Сертификаты, которые подразумевают возможность подписывать другие сертификаты, называются сертификатами удостоверяющих центров (УЦ). Как ни странно, но в технической части TLS роль УЦ на этом заканчивается: УЦ – это просто флаг в сертификате (флаг называется CA).

3.

Аутентификация по TLS-сертфикатам основана на следующем простом алгоритме: сторона, “подлинность” которой проверяется, по запросу подтверждает, что ей известен секретный ключ, соответствующий открытому ключу из доверенного сертификата. Это означает, что если сертификат для аутентификации предъявляет сервер, то сервер должен знать секретный ключ от этого сертификата. Обычно, доступ к секретному ключу тем или иным образом настраивается в конфигурации сервера. В наиболее распространённом сейчас случае, – например, для HTTPS, – секретный ключ просто размещается в файле на сервере, путь к файлу ключа указывается в конфигурации.

Электронная подпись, применяемая в отношении TLS-сертификатов, основана на той или иной асимметричной криптосистеме. В подавляющем большинстве случаев это ECDSA (современный вариант) или RSA (стремительно устаревающий вариант). Используется пара связанных между собой ключей: открытый и секретный. Секретный ключ позволяет вычислить соответствующее сообщению значение электронной подписи (это одно или несколько чисел), которое можно проверить с использованием открытого (публичного) ключа. В случае серверного сертификата и TLS – секретный ключ от сертификата используется для подписывания специального сообщения, определяемого клиентом. Проверка подписи, вычисленной сервером для заранее неизвестного ему сообщения, позволяет клиенту убедиться, что сервер знает “правильный” секретный ключ. Кроме того, в устаревших схемах TLS секретный ключ RSA (важно: именно RSA) используется сервером для расшифрования переданного клиентом сессионного секрета. Сейчас использование такой схемы не рекомендуется, а в самой современной версии, в TLS 1.3 – прямо запрещено.

4.

Доверие сертификатам – эквивалентно доверию представленным в них открытым ключам. Методы управления таким доверием находятся за рамками TLS, но, тем не менее, составляют существенную часть практики TLS.

Обычно, доверие сертификатам строится по цепочке, от корневого, через промежуточные, до серверного (оконечного) сертификата. Цепочка выстраивается через подписи: ключ из корневого сертификата позволяет проверить подпись на промежуточном, а ключ из промежуточного – на серверном. Ранжируются и “сцепляются” сертификаты по именам: в каждом сертификате есть поля Issuer (“Издатель” – тот, кто удостоверил сертификат) и Subject (“Субъект” – тот, кому сертификат выдан); поле Issuer сертификата более низкого уровня должно соответствовать полю Subject сертификата более высокого уровня. Корневой сертификат всегда самоподписанный, то есть, у него значение поля Issuer равно значению поля Subject. Таким образом, корневой сертификат – всего лишь способ публикации доверенного корневого ключа. На практике, в Интернете, серверный сертификат в поле Subject содержит некоторое сетевое имя (реже – IP-адрес) сервера. При этом, если речь идёт о вебе, – а именно, о браузере и HTTPS, – то серверный сертификат обязательно должен содержать имя (возможно, IP-адрес) сервера и в специальном дополнительном поле SAN (Subject Alternative Name), иначе современные браузеры будут считать такой сертификат невалидным (то есть, соединение с сервером будет отмечено как “недоверенное”). На начальном этапе установления TLS-соединения сервер передаёт один или несколько сертификатов клиенту. Так, в современной практике HTTPS, корректно настроенный сервер практически всегда передаёт, как минимум, один серверный и один промежуточный TLS-сертификат.

Отсутствие промежуточного сертификата на стороне сервера является очень распространённой ошибкой настройки. При этом, так как браузеры кешируют промежуточные сертификаты, а в некоторых браузерах распространённые промежуточные сертификаты входят в типовой дистрибутив, такая ошибка может быть незаметна для конкретного экземпляра браузера, а в других – будет проявляться.

В TLS возможна аутентификация как сервера клиентом, так и клиента сервером, однако последний случай используется реже. Аутентификация клиента проводится по тем же принципам, что и аутентификация сервера: проверяется наличие секретного ключа, соответствие имён (для клиента – это может быть некоторое имя пользователя, логин), выстраивается цепочка к некоторому доверенному сертификату, известному серверу.

5.

TLS защищает передаваемые данные от прослушивания, это делается при помощи шифра. Формально, всё ещё возможно реализовать TLS-соединение, не зашифровывающее данные, но это скорее теоретическое упражнение.

Для защиты данных используется симметричный шифр, обычно, это AES или ChaCha20. Симметричный шифр здесь – это шифр, который использует секретный ключ, одинаковый для обеих сторон соединения. В TLS эти ключи называются ключами защиты трафика. TLS-соединение использует пару ключей на каждой стороне: один ключ для записи (передачи) данных, второй – для чтения (приёма); это, всего лишь, означает, что клиент зашифровывает данные, отправляемые в сторону сервера, с одним ключом, а расшифровывает полученные от сервера данные – с другим; на стороне сервера ключи меняются местами – тот, что у клиента для записи, у сервера – для чтения. Эта пара ключей не имеет ничего общего с парой секретный/открытый ключ из области асимметричных криптосистем: здесь просто два секретных симметричных ключа.

Помимо того, что передаваемая информация зашифрована, TLS также обеспечивает её целостность, то есть, позволяет обнаружить изменение защищённого пакета в процессе доставки, провести аутентификацию данных. Для этого служат коды аутентификации сообщений (MAC, а в русскоязычной терминологии – имитовставка). Такой код, вычисленный по особому алгоритму, прикрепляется к сообщению. Чтобы сгенерировать корректный код для заданного сообщения нужно знать секретный ключ. Принимающая сторона, которой секретный ключ известен, может проверить, что код соответствует сообщению, следовательно, сообщение вряд ли было изменено. Современный метод применения шифров в TLS объединяет процесс зашифрования и процесс защиты целостности данных в единый алгоритм, называемый “аутентифицированным шифрованием”. Распространённый пример такого алгоритма – AES-GCM.

6.

Сеансовые секретные ключи, используемые сторонами для защиты трафика, генерируются на начальном этапе установления TLS-соединения. Современный способ получения этих ключей в TLS построен на базе протокола Диффи-Хеллмана (DH). Это означает, например, что сеансовые ключи не зависят от секретного ключа, связанного с сертификатом сервера (однако этот ключ всё равно используется в процессе установления соединения, для аутентификации, как описано выше). Протокол Диффи-Хеллмана позволяет добиться так называемой “прогрессивной секретности”, то есть, состояния, когда временные, сеансовые ключи защиты трафика конкретной сессии нельзя получить из долговременных ключей, к которым, прежде всего, относится ключ аутентификации (соответствующий сертификату). Другими словами, если сеансовые ключи, корректным способом полученные по протоколу Диффи-Хеллмана, уничтожаются после завершения сеанса, то сторона, которой позже станет доступен долговременный секретный ключ, всё равно не сможет простым способом восстановить сеансовые ключи из записи трафика (см. впрочем, отдельную записку о ключах и DH). Это важнейшая особенность данного протокола в TLS, которая строго закреплена в версии 1.3.

7.

Всё это означает, что если вы возьмёте, например, tcpdump и взглянете на трафик, передаваемый через TLS-соединение, то увидеть полезную нагрузку так просто не получится – вместо неё вы обнаружите поток байтов, очень похожих на случайные. Поэтому, если у вас веб-сервер отвечает по HTTPS, то есть, через TLS, то нельзя простым способом проксировать или как-то обрабатывать HTTP до веб-сервера, так как даже увидеть HTTP-запросы в трафике можно либо только “внутри” веб-сервера (после того, как TLS “раскрыт”), либо их можно увидеть снаружи, но используя некоторые, достаточно сложные, специальные методы.

Специальные методы для (пассивного) чтения полезного содержимого TLS-трафика используют ключи защиты трафика. Для того, чтобы внешнее приложение могло просматривать TLS-трафик, в сторону этого приложения достаточно экспортировать сеансовый секрет, который служит основой для генерации ключей защиты трафика, либо сами эти ключи. Возможность такого экспорта определяется настройками TLS-сервера или TLS-клиента. Сеансовый секрет и наборы ключей у сервера и клиента общие (в одной сессии), поэтому извлечь нужное значение можно с любого из узлов. На стороне сервера, обычно, экспорт секретов/ключей настраивается в конфигурации серверного приложения, иногда включить такой экспорт можно через соответствующую переменную окружения (например – SSLKEYLOGFILE). Аналогично – на стороне клиента. Суть данного метода следующая: криптографическая библиотека, обеспечивающая работу TLS, будет выводить в файл с заданным именем некоторый идентификатор TLS-сессии и соответствующий сеансовый секрет; получив секрет, приложение для анализа трафика сможет вычислить сеансовые ключи и расшифровать трафик. Передавать секрет через файл, конечно, необязательно. Очевидно, такой метод создаёт некоторую задержку и лучше подходит для анализа записанного ранее трафика. Аналогичный метод может работать и в режиме онлайн, но это потребует гораздо более плотной интеграции программных пакетов. Экспорт сеансового секрета является сейчас самым универсальным и технологичным способом анализа TLS-трафика, но, обычно, работает для ранее записанных сессий – например, в таком режиме можно использовать Wireshark. Существует устаревший способ, основанный на передаче секретного ключа RSA. Этот способ, по описанным выше причинам, не подходит для сессий, в которых вычисление сеансового секрета происходит по протоколу Диффи-Хеллмана, а это большинство сессий с современными настройками. Специально выбирать ключевой обмен RSA при настройке TLS, чтобы получить простую возможность анализа трафика, крайне не рекомендуется.

8.

TLS-терминирование – это практика, которая подразумевает “раскрытие” TLS на некотором входном “рубеже” сервиса и последующую работу с трафиком в открытом виде. Один из сценариев описан в начале этой статьи (stunnel и DNS-сервер). Другим примером является применение веб-сервера nginx (как один из вариантов) в качестве обратного прокси, который внешние соединения осуществляет по протоколу HTTPS, а внутренние, то есть, в сторону бекэнда, уже в открытом виде, по HTTP. TLS-сертификаты, секретный ключ от серверного сертификата, параметры TLS – всё настраивается в nginx. При этом сам основной сервис (бекэнд) может работать на другом физическом узле. Такая архитектура, например, позволяет просматривать, анализировать и изменять HTTP-трафик на пути от обратного прокси к сервису. Более того, в данном случае возможна балансировка HTTP-запросов уже после проксирования, нужно только правильно учитывать, что, к моменту поступления HTTP-трафика на так поставленный балансировщик, этот трафик уже успел нагрузить проксирующий сервер, в том числе, в части TLS, а это может оказаться существенно.

Качественное внешнее обслуживание запросов, “завернутых” в TLS, так или иначе требует “разворачивания” трафика и передачи секретных ключей. Например, передача секретного ключа от серверного сертификата позволяет промежуточному узлу прозрачно анализировать защищённый трафик, так как узел успешно аутентифицируется клиентом. Существуют схемы, когда в сторону проксирующего (или фильтрующего) узла отдаётся не сам секретный ключ от сертификата, а только интерфейс для получения подписи от этого ключа. Первая массовая реализация такого подхода – это Keyless SSL у Cloudflare.

9.

Итак, современный TLS-сервер должен поддерживать версию протокола 1.3 и, в качестве дополнительной версии – 1.2, все предыдущие версии не рекомендуются, и могут присутствовать только в случае строгой необходимости доступа для каких-то устаревших клиентов. Для TLS-сертификата сервера лучше выбрать криптосистему ECDSA, но при этом нужно обратить внимание, что вся цепочка сертификатов поддерживает ECDSA, в противном случае – смысла в ECDSA сильно меньше. Криптосистема RSA, хоть и является устаревшей, но всё ещё может применяться, особенно, когда других вариантов нет, как с современной (2021) версией бесплатного УЦ Let’s Encrypt. TLS-сервер обязательно должен использовать протокол Диффи-Хеллмана для получения сеансового секрета (это актуально только для старых версий TLS). В настройках серверов данный протокол обозначается как DH, ECDH или ECDHE. Шифр для защиты трафика должен работать в режиме аутентифицированного шифрования, подходит, например, AES-GCM.

Если вас заинтересовали подробности, то в качестве отдельной публикации доступно детальное техническое описание TLS.

Некоторые другие записки по теме на dxdt.ru:

Популярно о перехвате HTTPS

DNS-over-TLS на авторитативных серверах DNS

“Ключи на клиенте” и протокол Диффи-Хеллмана



Комментировать »

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

“Итак, классический телефонный аппарат позволял без особых сложностей прослушивать помещение, где он установлен. Но только в том случае, если аппарат подключен к телефонной розетке. Отключили – данная конкретная утечка невозможна.”

Занятно, что при установке телефонных аппаратов в защищаемых помещениях специалисты инженерно-технической защиты монтировали специальную “кнопку”, которая, при нажатии, полностью развязывала аппарат с входящей телефонной линией (это делалось механически: перекоммутацией входной телефонной пары на гальваническую заглушку). Сейчас аналогичные меры организуются иначе: например, если смартфон нельзя изъять, то владельцу предлагается поместить его в некоторый специальный ящик, находящийся в том же помещении, но выполняющий экранирующие функции. (В скобах замечу, что данный процесс не то чтобы сильно лучше варианта, при котором личный смартфон предлагается сдать в какое-нибудь хранилище на другом этаже, но почему-то считается, что раз коробка со смартфонами находится на виду, то незаметно сделать с этими смартфонами ничего нельзя. Это, впрочем, другая история.)

“Первые мобильные телефоны, надо сказать, устраняли каналы утечек по проводам, ввиду отсутствия последних. Взамен, до введения приемлемого шифрования, телефонные разговоры стало возможно прослушивать в эфире.”

Вообще, появление личного носимого “радиомаяка” – очень важный аспект. Сейчас этот “радиомаяк” используют всё шире: для идентификации “абонента-носителя” в потоке других “пассажиров”, для обнаружения и записи контактов (например, в маркетинговых программах); вполне вероятно, что в скором времени человек без “активного смартфона” будет автоматически, повсеместно выделяться системами наружного наблюдения и отмечаться как “подозрительный”.

“Самая главная новинка мобильной связи, в контексте нашей истории, – это возможность определения географического положения носителя жучка. Определить местоположение можно быстро, удалённо, и чисто техническими средствами. Принципиально новая функция, недоступная ранее. Сигнал аппарата содержит уникальные метки. Для определения положения нужны несколько приёмников, специальное оборудование и навыки радиопеленгации.”

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

“Память аппарата вообще является фундаментом для целого ряда дополнительных функций жучка: тексты SMS, сведения о частотности звонков на те или иные номера, данные о взаимодействии аппарата с сетью оператора – это всё новые возможности.”

Понятно, что и в “старой телефонии” можно было вести лог звонков, в том числе, записывая конкретные вызываемые номера. Более того, массовый автоматизированный “биллинг”, который развился ещё до появления смартфонов, позволял делать сложные выборки по контактам заданного абонента “стационарной связи”. Но речь-то в исходной записке о том, что такие метаданные стал накапливать сам телефонный аппарат, а не специальное оборудование на узле связи. Это всё актуально и сейчас, с той лишь разницей, что теперь смартфон накапливает информацию с гораздо более широким спектром: сюда нынче входят разнообразные “показатели здоровья” (читай – биометрические данные), сведения о “контактах” с другими смартфонами, находившимися рядом, информация о доступе к тому или иному контенту (не только на интернет-сайтах, но и через разные SmartTV и им подобные “говорящие кофеварки”).

“Удачное сочетание функций определения положения в пространстве, измерения ускорений (тот или иной “гироскоп”, как известно, тоже наличествует в смартфоне) и ориентации аппарата, а также получения фотоснимков и анализа сигналов WiFi, уже позволяет картографировать места обитания носителя жучка в удивительных подробностях, позволяющих построить детальную 3D-модель его квартиры, вместе со всем внутренним убранством.”

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



Комментировать »

Какими базовыми свойствами должно обладать приложение (например, для смартфона) и соответствующий сервис, которые претендуют на роль современного суперзащищённого мессенджера? Часть “супер-” – здесь важна. Это не конкретные технические свойства, а, скорее, свойства-признаки, позволяющие строить предположения о реальной безопасности и “приватности” приложения. Дело в том, что про такие приложения периодически делают какие-то заявления, в стиле, что “разработали” или “разработают”, но далеко не всегда заявления сопровождаются подробным содержательным описанием проекта. Все приведённые ниже свойства довольно трудно реализовать, а сам список – скорее иллюстрирует сложность построения системы. Возможно, подобных популярных приложений пока не появилось именно по причине этой сложности.

Естественно, конкретный набор свойств, их интерпретация – зависят от выбранной модели угроз. В нашем случае, с целью экономии букв, конкретная модель угроз вынесена за скобки. Так как описываемые свойства это не технические требования, а признаки, позволяющие составить предварительное мнение о степени безопасности конкретного типа приложения, просто встанем на “фольклорную” точку зрения и предположим, что гипотетический мессенджер должен защищать от продвинутого технического противника, который перехватывает и подменяет трафик, а также может проводить другие активные атаки на любых технических уровнях. Поэтому в список даже не входят рассуждения о том, что типичный смартфон-носитель не контролируется его пользователем, а уже одно это легко сводит к нулю все утверждения о защищённости приложения.

Итак, список свойств. Некоторые из них совсем очевидны, некоторые – очевидны в меньшей степени, есть и неочевидные.

1. Ни в каком виде не должно быть авторизации по телефонному номеру. Тем более – привязки аккаунта к телефонному номеру. Телефонный номер – это ресурс оператора связи. Следует считать, что оператор связи решает собственные задачи и вовсе не собирается участвовать в обеспечении безопасности очередного “безопасного” мессенджера.

2. Не должно быть централизованного инструмента для “восстановления аккаунта”. То есть, если пользователь совсем потерял все свои реквизиты доступа, то, к сожалению, это означает, что он потерял и доступ, без возможности восстановления. Дело в том, что наличие централизованного инструмента восстановления аккаунта (типа, “получите код в SMS”), означает, что внутри мессенджера встроен механизм перехвата аккаунтов. Ключевое понятие здесь: “централизованный”. Это, естественно, не отменяет дополнительных резервных реквизитов и защищённых распределённых инструментов восстановления доступа.

3. Идентификация аккаунта проводится по отпечатку некоторого криптографического ключа (или “токена”), секретная часть которого находится у пользователя. Этот принцип соблюдается далеко не всегда, но только такой вариант позволяет разделить “адресацию” на уровне сообщений пользователей и всю прочую адресацию (IP-адреса узлов, доменные имена, телефонные номера и пр.). Привязка идентификатора к реальному пользователю происходит за пределами мессенджера.

4. Протоколом обмена сообщениями должен быть предусмотрен механизм внешней доверенной проверки подлинности ключей и идентификаторов. Это, грубо говоря, некоторый способ, позволяющий без использования самого мессенджера проверить, что предъявленный конкретному пользователю ключ другого пользователя – действительно принадлежит этому другому пользователю, а не промежуточному серверу (например).

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

6. Исходный код приложений (клиентских, серверных, “промежуточных” и пр.) должен быть открыт и опубликован. Так сказать, в “максимальной разумной общности”: то есть, вместе со всеми “дополнительными библиотеками”, если таковые используются существенным образом. Это не означает, что нужно включать в состав кода приложения, скажем, реализацию IP из модулей ядра ОС: потому что логика мессенджера не должна зависеть от реализации сетевого транспорта. Публикация исходных кодов, пожалуй, самый непрозрачный момент. С одной стороны – само по себе раскрытие исходников не гарантирует ни отсутствия ошибок, ни отсутствия закладок (да и вообще ничего не гарантирует); с другой – ожидать, в данном случае, какой-то особой защищённости от приложения с закрытым кодом ещё труднее (см. следующий пункт). Код должен быть обозримым (а этого трудно достигнуть).

7. Необходимо наличие документированной и открытой процедуры, которая позволяет из исходного кода получить исполняемый код и проверить, что, во-первых, получилось то, что планировалось, во-вторых, что у всех пользователей получились одинаковые (возможно, с точностью до платформы и окружения) приложения. К сожалению, точное выполнение этого пункта на практике недостижимо, если говорить о сколь-нибудь сложном приложении. Но можно попытаться приблизиться. Понятно, что в процесс доверенной сборки должны включаться и доверенные компиляторы/интерпретаторы. С другой стороны – очевидно, что даже совпадающие побайтно исполняемые файлы могут вести себя различным образом при исполнении в конкретных условиях (зависит от входных данных, системного окружения и т.д.). Однако в публикации неких исходных кодов без проверки того, что используемое всеми приложение действительно как-то с этими кодами связано, тоже смысла не так много, как хотелось бы. Ну, если говорить о гипотетическом суперзащищённом приложении, на практике-то – с лёгкостью используются “бинарники” из дистрибутива ОС.

8. Приложение должно быть максимально независимым от аппаратной платформы и операционной системы. То есть, не должно быть, например, строгой привязки к конкретному “типу смартфонов” или к конкретной компании-разработчику, которая, скажем, славится громкими заявлениями о “своей приверженности обеспечению приватности пользователей”. Вообще, всякая подобная привязка должна наводить на подозрения, что не так всё просто с этим “супербезопасным мессенджером”.

9. Предпочтительно должна использоваться распределённая схема доставки сообщений. Дело в том, что доступность – один из основных критериев супербезопасного мессенджера. Обеспечить гарантированную доступность через центральный сервер весьма сложно (скорее – невозможно): на этом сервере всегда можно отключить, заблокировать кого-то из пользователей. Опять же, это весьма и весьма трудный в реализации пункт, хоть и популярный.



Комментарии (8) »

Сделал небольшой шуточный проект – утилита кодирования двоичных данных, аналогично Base32, но на основе англосаксонских (древнегерманских) рун. Код доступен на GitHub. Base32 это алгоритм кодирования данных, использующий латинский алфавит. Он устроен аналогично несколько более широко известному Base64. Смысл использования подобных схем кодирования в том, чтобы отобразить произвольные “двоичные данные” в алфавит, который можно передать через “текстовый канал”, например, электронной почтой (или даже в виде простой распечатки). Конечно, с рунами этот фокус не сработает. Поэтому – проект шуточный.

Руны входят в таблицы Unicode. (“Обобщённые” символы Unicode тоже называют рунами, но в нашем случае – речь про конкретное подмножество, про англосаксонские руны.) Используемое кодирование (представление Unicode) занимает по три байта на каждую руну. При этом для записи 40 битов (пять байтов) в Base32 используется 8 символов: каждый символ несёт пять битов, откуда, собственно, число 32 == 2^5. То есть, получается, что Base32 на основе рунического письма в Unicode превращает пять байтов исходных данных в 24 байта (восьмибитных) закодированного текста. Не очень-то экономно. Оригинальный вариант Base32, построенный на латинском ASCII-алфавите и ASCII-цифрах, даёт результат лучше: пять байтов кодируются восемью байтами (если при кодировании текста используется привычное, 8-битное, представление байта). Но руны выглядят интереснее, что подтверждается скриншотом ниже, на котором запечатлён TLS-сертификат, записанный в runic32.

Runic Text

Примеры использования утилиты, написанной на Go, приведены на странице репозитория Runic32 в GitHub.



Комментарии (2) »

На dxdt.ru с 2016 года опубликована небольшая криптографическая библиотека для Arduino, построенная на российском шифре “Магма”. Мне иногда присылают сообщения о проблемах (ошибках, выводимых компилятором), которые возникают при сборке в новых версиях Arduino IDE. Собственно, решение упоминается в комментариях к странице, но я всё же добавил в основной текст подробное пояснение о причине трудностей и о том, как эти трудности победить. Кратко: проблема не в коде библиотеки, а в установленном по умолчанию уровне оптимизации компилятора – в старых версиях Arduino IDE установки были другие. Библиотеку можно использовать без изменений, но нужно подредактировать настройки IDE (штатным способом); второй вариант – использовать обновлённую библиотеку, где параметры оптимизации указаны в исходном коде. Подробности – на странице библиотеки.



Комментировать »

Обновления на сервере tls13.1d.pw, который предназначен для тестирования реализаций TLS версии 1.3 и сопутствующих технологий:

1) появилась поддержка ротации (обновления) симметричных ключей сессии. Речь про механизм Key Update, который в TLS применяется для того, чтобы узлы могли перейти на новые ключи внутри уже установленной сессии. Новое поколение ключей вычисляется на основе данных предыдущего поколения. Есть два варианта схемы обновления: на новые ключи либо переходит только один узел, либо оба узла. Для управления обновлением служит TLS-сообщение KeyUpdate. Сервер tls13.1d.pw поддерживает инициированное клиентом обновление (в двух вариантах – с обновлением серверных ключей и без оного), а также, с вероятностью примерно 1/3, может сам передать сообщение KeyUpdate, соответствующее замене серверных ключей (и заменить ключи);

2) теперь сервер перемешивает на своей стороне приоритеты шифронаборов при каждом соединении. Это означает, что могут быть выбраны разные шифры для разных соединений, но для одних и тех же настроек на стороне клиента. В предыдущих версиях приоритеты были зафиксированы, а наивысшее значение имел шифронабор CHACHA20_POLY1305_SHA256. Поэтому, если в качестве клиента выступал, например, браузер Chrome со стандартными настройками, то всегда согласовывался шифронабор с CHACHA20. При этом сервер поддерживает ещё AES в вариантах с 128- и 256-битным ключом. Теперь AES тоже будет иногда выбираться и для клиентов, у которых есть CHACHA20 (естественно, клиент должен заявить поддержку AES);

3) в части, реализующей элементарный веб-сервер, появилась чуть более развитая поддержка URL и кодов статуса HTTP. Теперь сервер различает адреса документов и даже умеет отдавать разные файлы при обращении по разным адресам. Это последнее новшество позволило добавить передачу файла стилей (CSS) и сделать некоторое минимальное оформление страницы результатов (но, собственно, эта часть обновлений не имеет отношения к TLS).

Что касается KeyUpdate, то здесь поддержка браузерами имеет некоторые ограничения: инициировать ротацию ключей на стороне браузера пользователь не может, однако успешная замена серверных симметричных ключей будет отражена на странице результата – там дописывается сообщение о такой замене (интересно, что если браузер на своей стороне ключ не поменял, то расшифровать данные страницы окажется невозможно и пользователь так или иначе не увидит сообщения об успешной ротации ключей). При желании, посмотреть на то, как работает KeyUpdate, можно с помощью утилиты s_client из OpenSSL (нужна современная версия): в s_client есть специальные интерактивные команды ‘k’ и ‘K’ (строчная и заглавная буквы), которые позволяют отправить KeyUpdate с флагами двух видов – замена ключей только одним узлом (k) или обоими узлами (клиентом и сервером).

Описание возможностей сервера есть в отдельной записке.



Комментировать »

Добавил к техническому описанию TLS совсем краткое приложение, рассказывающее про DNS-over-HTTPS и DNS-over-TLS как примеры использования TLS для защиты других протоколов. Так как это приложение, и оно небольшое, основную версию документа решил не менять.

Вообще, в этом году обновлений для описания TLS получилось не так много. В июле я внёс исправления и уточнения в основной текст, добавил описание ESNI и приложение, рассказывающее на элементарном уровне о некоторых математических аспектах криптографии на эллиптических кривых (на мой взгляд, это довольно полезное приложение). Посмотрим, как будет развиваться тема в следующем году.



Комментировать »

Photo: AJenyonНа Wired небольшая заметка (англ.) о том, что системы “искусственного интеллекта”, которые построены на основе популярных сейчас методов машинного обучения, могут содержать в себе алгоритмические закладки, приводящие, в случае активации, к неожиданным эффектам. Это довольно старая тема, но сейчас она начинает проникать в популярные СМИ.

Речь идёт о том, что на этапе обучения в систему могут быть специально заложены сценарии, срабатывающие в строго определённых условиях. Например, при демонстрации конкретного изображения. Хитрость состоит в том, что обнаружить наличие таких сценариев, или как-то гарантировать, что их нет, – чрезвычайно сложно. Дело в том, что современное машинное обучение, грубо говоря, это автоматизированный подбор огромного количества коэффициентов, составляющих некоторые уравнения (или формулы). Получающийся в типичном случае результирующий набор данных, часто называемый “обученной нейросетью”, настолько огромен, что полностью необозрим даже для автоматизированных методов анализа.

Готовая нейросеть работает очень быстро, поскольку задача вычисления результата применения нейросети к конкретному набору входных данных – простая, в вычислительном смысле. В этом, собственно, и состоит удобство: можно быстро получить более или менее приемлемый результат – распознать объект, выбрать сценарий действий и пр. Однако обратная задача, в которой всем возможным значениям на выходе сопоставляются входные значения (то есть, прообразы), оказывается чрезвычайно сложной, требующей больших вычислительных мощностей, если она вообще разрешима на практике.

Представьте, что есть нейросеть, которая обучена узнавать наличие дикобразов на фотографии. В простейшем случае, вы применяете нейросеть к конкретному изображению, а на выходе получаете один бит: “есть дикобраз” – 1; “нет дикобраза” – 0. Пусть входное изображение имеет допустимые размеры в 1 млн пикселей (1000×1000 – это не важно). Посчитать выходной бит нейросети для любого фотоснимка очень просто, компьютер справляется за малую долю секунды. Но развернуть биты обратно, разбив все допустимые входные изображения на два класса (“есть дикобраз”/”нет дикобраза”), очень сложно, так как нейросеть состоит из тысяч коэффициентов, выстроенных в несколько слоёв (или представленных как система уравнений, это не принципиально) – граф состояний нейросети огромен. А перебрать все возможные сочетания пикселей, скармливая нейросети тестовые изображения – и того сложнее. Соответственно, может существовать сочетание пикселей, при наличии которого любой дикобраз, хорошо видимый на картинке, узнан не будет, с гарантией. Просто, на этапе обучения “нейросети” такие картинки специально подсовывались в выборку и отмечались как “здесь точно нет дикобраза”. Это и есть алгоритмическая закладка. Конечно, в несколько утрированном виде, но общая логика – именно такая.

Так что обнаружить алгоритмическую закладку на практике нельзя, а работать эта закладка будет идеально, даже точнее, чем все прочие возможности нейросети. И нейросеть, призванная распознавать объекты в видеопотоке и используемая в системе контроля доступа, станет игнорировать присутствие в кадре людей, надевших маску Микки-Мауса – они смогут беспрепятственно перемещаться по охраняемой территории.



Комментарии (1) »

Очень много сообщений про DNS-over-HTTPS в Firefox, про то, что внедрение этого протокола, якобы, “позволяет обходить любые блокировки и DPI”. Между тем, DNS-over-HTTPS (DoH) в Firefox – это способ сокрытия DNS-запросов и DNS-ответов от третьей стороны, причём скрываются только запросы от браузера до рекурсивного резолвера (подразумевается, что до резолвера Cloudflare). Заметьте, что использование DoH не скрывает рекурсивные запросы, источником которых является браузер Firefox. Например, если некоторую уникальную DNS-метку встроить в веб-страницу, то на авторитативном сервере будет видно, откуда пришёл рекурсивный запрос, соответствующий конкретной сессии конкретного браузера. По IP-адресу источника запроса (рекурсивного резолвера), по некоторым другим признакам, можно определить, используется ли клиентом штатный DNS от провайдера доступа, или это та или иная реализация DoH. В качестве источника DNS-меток (такой источник принято называть “праймером”) с большим охватом может работать любой популярный веб-сервис или веб-сайт: например, какой-нибудь веб-счётчик (что-то подобное “Яндекс.Метрике”), страница популярной социальной сети и т.д.

Однако на пути от браузера до рекурсивного резолвера, действительно, запросы и ответы DNS не будут видны третьей стороне, просматривающей трафик, так как они в HTTPS защищены шифрованием. Но к “обходу блокировок” это относится весьма косвенно.

Предположим, что блокировка доступа к веб-ресурсу осуществляется провайдером на уровне DNS. Смысл подобного метода блокирования в том, чтобы браузер (или другие программы-клиенты) не мог определить подлинный IP-адрес, с которым требуется установить соединение. Как такая блокировка работает?

В простом варианте, провайдер так настраивает резолвер, обслуживающий клиента, что в ответ на запрос о заблокированном ресурсе (по имени домена) – резолвер возвращает не подлинный IP-адрес, а либо адрес сервера-заглушки, либо заведомо недоступный адрес. Чтобы это работало, клиент должен использовать DNS провайдера. Эта схема реализуется самыми элементарными средствами. Для её преодоления не требуется ничего зашифровывать, а достаточно использовать другой DNS-резолвер, не провайдерский.

В продвинутом варианте, уже система DPI обнаруживает все DNS-запросы и DNS-ответы, вне зависимости от того, к каким DNS-серверам они отправлены и от каких получены. Фильтрующий узел вмешивается в трафик в том случае, если силами DPI обнаружены запросы, относящиеся к заблокированным именам. Вмешательство в трафик может выражаться как в подмене ответов, так и в блокировании запросов; конечно, можно заблокировать и ответы. В этом случае DoH помогает, так как DPI перестаёт видеть DNS-трафик. Однако тот же фильтрующий узел и DPI можно настроить так, что они будут блокировать трафик DoH. Блокировать придётся весь трафик, а DPI потребуется очень серьёзно доработать. При этом в Firefox по умолчанию будут встроены средства, позволяющие предотвратить автоматическое включение использования DoH. Эти средства предназначены для корпоративных сетевых сред, где фильтрация DNS нередко является обязательным требованием “политик безопасности”. Такое поведение браузера пользователь может преодолеть, если включит использование DoH вручную.

(Отмечу, в скобках, что все описанные выше методы с подменой информации DNS противоречат DNSSEC и, соответственно, будут обнаружены, если клиент поддерживает DNSSEC.)

Защита от просмотра DNS-трафика никак не влияет на блокировку доступа непосредственно по IP-адресу узла: если соединение с конкретным адресом установить не удаётся, то не важно, как этот адрес был получен – через “открытый DNS” провайдера или через “защищённый DNS-over-HTTPS”. Да, нетрудно предложить вариант, в котором IP-адреса постоянно изменяются, а “верный адрес” передаётся только при использовании сервиса DoH. Так можно устроить, если авторитативные серверы DNS соответствующей доменной зоны как-то связаны с провайдером сервиса DoH. Однако при этом активная система блокирования может узнавать “верные адреса”, просто используя свой экземпляр браузера Firefox. Конечно, всегда остаётся экстенсивный вариант развития данной схемы, при котором, с одной стороны, сотни тысяч IP-адресов случайно распределяются по DNS-ответам, а с другой стороны – какие-то, – возможно те же, – сотни тысяч и миллионы адресов попадают под превентивную блокировку. При этом DoH здесь помогает только тем сервисам, у которых очень много IP-адресов.

Нередко можно услышать, что данный метод, применительно к проблеме блокирования доступа, хорош тем, что его трафик, по внешним признакам, не отличается от “обычного HTTPS” (то есть, от HTTPS для веб-сайта). Мало кто готов блокировать весь HTTPS-трафик. Конечно, приложив достаточно вычислительных мощностей, попытаться отличить трафик DoH от работы с веб-сайтами – можно: есть IP-адреса, есть характеристики отправляемых и принимаемых пакетов, продвинутая система блокирования умеет делать проверку сервисов (connection probe) и так далее. Другое дело, что ресурсов для блокирования потребуется действительно много и будут ложные срабатывания. Более того, в качестве следующего шага по защите возможно заворачивание DNS-трафика в “самый настоящий” HTTPS-сеанс работы с обычным веб-сайтом: DNS-запросы могут передаваться браузером в качестве нагрузки, в специальных HTTP-заголовках; и в таких же HTTP-заголовках сервер пришлёт ответы.

В целом, сверхидея DNS-over-HTTPS хорошо укладывается в самую современную концепцию в области информационной безопасности. В этой концепции “доверенными” являются только приложения – клиентское и серверное. То есть, даже операционная система не относится к доверенным. Криптография позволяет двум приложениям надёжно идентифицировать (и аутентифицировать) друг друга: браузер Firefox, используя принесённые с собой TLS-сертификаты, идентифицирует и аутентифицирует серверное приложение, которое исполняется на узлах Cloudflare и реализует сервис рекурсивного опроса доменных имён. Для схемы не важно, каким образом, по каким транзитным сетям, приложения устанавливают между собой соединение. Да, тут есть масса оговорок – про аппаратуру, которая исполняет команды; про ядро ОС, имеющее полный доступ к памяти приложений; и так далее. Но, тем не менее, логическая концепция именно такая. Развитие этой идеи в ближайшем будущем приведёт к тому, что появятся “различные интернеты”, работающие внутри того или иного приложения. Но это другая история.

Вернёмся к DoH в браузере Firefox. Данный инструмент, сам по себе, не является универсальным средством, “позволяющим обходить все блокировки”, но он защищает от утечки информации о DNS-запросах/DNS-ответах на “последней миле”: то есть, на пути от резолвера до браузера. При этом браузер замыкает на стороне пользователя некоторый особый контур, в который теперь входит и защищённая доставка контента (TLS на веб-сайтах), и собственный сервис доменных имён. “Интернет – это то, что показывается в браузере”.



Комментарии (4) »
Навигация по запискам: Раньше »