ksks7 (Техничная записка из области популярной криптологии, которая, думаю, будет полезна и на dxdt.ru.)

Нередко можно услышать, что сеансовые ключи, полученные сторонами по протоколу Диффи-Хеллмана (DH), есть только у клиента и сервера, а больше нигде не сохраняются. Очевидно, что и сервер, и клиент сохраняют ключи у себя на некоторое время, как минимум, пока обмениваются данными в одном контексте. Ключи могут храниться дольше, потому что есть механизм возобновления TLS-сессии. Но существует и другой аспект, про который забывают. В TLS-трафике, которым обменивались клиент и сервер, вообще говоря, содержится представление сеансовых ключей. То есть, то, что в открытом виде эти ключи не передаются, не означает, что они совсем не связаны с трафиком. На самом деле – ключи в трафике есть, просто их трудно извлечь, потому что они представлены в форме, которую сложно обратить. Случай некоторым образом похож на ситуацию с удалением файлов в целом ряде файловых систем: удалённый файл – всё ещё на диске, просто, его трудно найти. Естественно, вычислить сеансовые ключи из трафика существенно сложнее, чем восстановить файл.

Если третья сторона записывает TLS-трафик, то вместе с ним сохраняются и данные, послужившие источником сеансовых ключей (в случае использования DH). Фактически, можно говорить о том, что эти ключи тоже сохраняются вместе с записанным трафиком. В этом и состоит тонкость, относящаяся к области различий между реально уничтоженными (или отсутствующими) и зашифрованными данными. Для восстановления ключей DH из записи трафика нужно обладать дополнительной информацией (либо уметь решать вычислительные задачи, которые сейчас считаются трудными). К такой дополнительной информации относится, скажем, состояние генератора псевдослучайных чисел, который использовался на стороне сервера (или клиента) при выработке сеансовых параметров DH.

Когда говорят о прогрессивной секретности (PFS), которой позволяет добиться использование DH, то имеется в виду вовсе не то, что ключи невозможно восстановить после того, как сессия завершилась, а лишь то, что утечка долговременного ключа не раскрывает сессионных ключей. Не более того. Обычно, долговременный ключ в TLS – это ключ, используемый для аутентификации сервера, при помощи электронной подписи. Если прогрессивная секретность отсутствует, то восстановление сеансовых ключей, если у вас есть долговременный секретный ключ (это будет, соответственно, RSA) оказывается тривиальной задачей – просто расшифровываем исходные данные из трафика.

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

Для детального понимания ситуации нужно рассмотреть следующий случай: предположим, что стороны, обменивающиеся данными в рамках защищённой сессии, используют заранее известный им разовый (относительно сессии) набор секретных сеансовых симметричных ключей и, скажем, AES. То есть, симметричные ключи не генерируются при помощи обмена в рамках DH, а известны заранее. По каналу связи они не передаются, канал не используется для их генерации. (Аутентификацию оставим за скобками.) Пусть используется добротный режим потокового шифрования: генерируется ключевой поток (гамма), совпадающей по длине с открытым текстом, а шифротекст является результатом операции XOR над открытым текстом и ключевым потоком. Примерно так работает GCM (аутентификацию мы договорились оставить за скобками) и всякий другой “режим счётчика”. Так как полученный ключевой поток будет, вообще говоря, вычислительно неотличим от псевдослучайной функции, то для записавшей трафик стороны ситуация окажется, условно говоря, семантически неотличима от абсолютно стойкого шифрования.

Думаю, понятно, что при использовании DH ситуация отличается в корне: теперь в составе сеанса появляются открытые ключи DH, которые представляют собой новый вектор атаки, а кроме того – они сохраняются вместе с трафиком. А вот в предыдущем случае – физическое уничтожения носителя ключей, действительно, приводит к уничтожению и самих ключей.

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

(Впрочем, для AES тоже можно предложить научно-фантастический компьютер, решающий соответствующую систему уравнений: но такому компьютеру потребуется известный открытый текст, а для случая DH и логарифмирования – он не нужен.)



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

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



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

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



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

Одно из современных направлений в развитии технологий связи – это сверхкомпактные, экономичные модули, обеспечивающие передачу данных на большие расстояния. Основная область применения: различные датчики, управляющие устройства и прочие “умные” компоненты. LoRa – как раз относится к таким технологиям связи: миниатюрный модуль, радиомодем, потребляющий минимальную энергию и делающий возможной передачу данных на расстояние в километры (вплоть до десятков километров). LoRa – похоже, лидер по дальности. Однако данная область не исчерпывается одним протоколом: здесь также действуют ZigBee, Bluetooth 4.0, Sigfox и др. Но эта заметка о том, как LoRa работает в реальности, на живом примере пары бюджетных модулей от NiceRF. (С картинками.)

Читать полностью



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

(Поделюсь на dxdt.ru такой репликой про “ключи и шифрование”.)

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



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

Нередко спрашивают, что такое DNSCrypt и зачем это нужно. Некоторое время назад я уже писал про DNSCrypt, применительно к “Яндекс.Браузеру”, тогда речь шла о поддержке в бета-версии браузера. В этот раз посмотрим на технологию в подробностях, а “Яндекс.Браузер” послужит примером и источником лабораторных данных. Разбор пакетов я провожу в Wireshark, для которого написал небольшой парсер DNSCrypt (в терминологии Wireshark – это dissector, на языке Lua; штатного парсера DNSCrypt в Wireshark-е мне выявить не удалось).

DNSCrypt – это прокси-сервис, создающий защищённый канал между клиентским резолвером DNS и рекурсивным DNS-резолвером, исполняемым на сервере. У DNSCrypt, соответственно, две части: клиентская и серверная. Через трафик DNS, который штатно передаётся в открытом виде, могут утекать сведения о посещаемых сайтах. Кроме того, запросы DNS – распространённый вектор атак для подмены адресов. Замена адреса системного резолвера DNS на адрес подставного сервера является общим местом троянских программ уже много лет. То же самое относится к атакам на домашние роутеры. DNSCrypt позволяет зашифровать (а также – ограниченно защитить от подмены) и запросы, и ответы DNS. Предусмотрена возможность аутентификации сервера и клиента, но эта возможность не всегда используется. Вообще, тема сокрытия DNS-трафика (DNS Privacy) сейчас набрала заметную популярность. Кроме DNSCrypt, существует, например, протокол “DNS через TLS” (DNS over TLS – свежий RFC 7858, который, несмотря на некоторую “перевёрнутость”, выглядит не хуже DNSCrypt). Есть и другие разработки.

DNSCrypt. Протокол может использовать в качестве транспорта как TCP, так и UDP. На практике, предпочтение отдаётся UDP, если он доступен, но спецификация строго требует поддержки именно TCP (не UPD, поддержка которого опциональна). TCP, естественно, привлекает сессионной природой. Но UDP – гораздо быстрее, особенно для нагруженных сервисов. Из-за проблем с DDoS-атаками и некоторых других вопросов обеспечения безопасности, сейчас наметилось модное движение в сторону перевода максимального числа сервисов на TCP, это особенно касается DNS. Тем не менее, ниже я рассматриваю работу DNSCrypt только по UDP, так как это традиционный для DNS вариант. Рекомендованный номер (серверного) порта DNSCrypt – 443 (он обычно открыт в корпоративных сетях; практика использования 443/udp, например, является стандартной для целого ряда VPN и других сервисов; 443/tcp – это TLS/HTTPS, фундамент веб-сервисов). Впрочем, “Яндекс” в своей реализации DNSCrypt использует непривилегированный номер: 15353, вероятно, это связано с какими-то идеями по преодолению разнообразных сетевых барьеров.

Чуть подробнее о барьерах: никаких проблем с блокированием трафика DNSCrypt, при наличии такого желания у провайдера канала, не возникнет. Как будет ясно из описания ниже, этот протокол никак не пытается скрыть сам факт своего использования. В трафик данного протокола включаются стандартные маркеры, которые позволят обнаружить и зафильтровать пакеты даже на самом примитивном маршрутизаторе, с помощью нехитрого правила “в две строчки”. При этом, например, доступ для других TCP-сессий, работающих на 443 порту, сохранится.

В DNSCrypt установление сессии между клиентом и сервером начинается с обычного DNS-запроса, отправленного на адрес и соответствующий номер порта узла, который будет предоставлять функции резрешения (резолвинга) имён. Это запрос TXT-записи для имени специального вида (то есть, запрос уже можно легко зафильтровать). Например, в случае с сервисом “Яндекса”: 2.dnscrypt-cert.browser.yandex.net. Это специальное имя может быть не делегировано. Значение 2 – соответствует версии DNSCrypt. Актуальная версия – вторая. В ответ сервер должен прислать один или несколько сертификатов DNSCrypt (подчеркну: они не имеют никакого отношения к SSL-сертификатам).

DNSCrypt dump

На скриншоте – пакет с сертификатом от сервера DNSCrypt “Яндекса”.

Сертификат представляет собой набор из нескольких полей: версия сертификата, значение подписи, открытый ключ сервера, magic-байты для клиента (они послужат идентификатором клиентских запросов – сервер сможет понять, какой ключ использовать при ответе), серийный номер и срок действия.

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

В качестве криптографических примитивов DNSCrypt использует конструкции из шифра Salsa20 (XSalsa20), хеш-функции Poly1305 (для реализации аутентифицированного шифрования) и алгоритм X25119-hsalsa20 для выработки общего сеансового ключа (алгоритм использует эллиптическую кривую Curve25119 и хеш-функцию hsalsa20). Эти конструкции разработаны Даниэлем Бернштейном (Daniel J. Bernstein) и давно получили признание как весьма добротные. Алгоритм получения общего секрета (сеансового ключа) математически родственен алгоритму Диффи-Хеллмана. Отмечу, что общий секрет в данном случае можно восстановить постфактум, если станет известен соответствующий секретный ключ из пары серверных (или клиентских) ключей, это позволит расшифровать ранее записанный трафик, именно поэтому спецификация рекомендует использовать кратковременные ключи.

Шифр XSalsa20 в режиме аутентифицированного шифрования требует nonce длиной 192 бита (24 байта). Повторное использование одного и того же сочетания ключа и nonce не допускается. Это связано с архитектурой шифра XSalsa20 – повторное использование nonce приведёт к утечке: прослушивающей стороне станет известно значение XOR от пары соответствующих открытых текстов. Поэтому nonce должно быть каждый раз новым, но не обязательно случайным. Параметр nonce в DNSCrypt присутствует в двух воплощениях: клиентской и серверной.

Посмотрим на зашифрованный клиентский запрос, отправляемый “Яндекс.Браузером”.

DNSCrypt dump

Первое поле запроса – это клиентское значение magic (Client query magic bytes): здесь используется часть открытого ключа сервера, полученная ранее. При необходимости, данные “магические байты” могут служить сигнатурой, позволяющей выбирать в трафике запросы, отправляемые к DNSCrypt;
Следующее поле – кратковременный клиентский открытый ключ (Client public key);
Клиентское значение nonce – 96 бит (12 байтов), половина от требуемого значения nonce для шифра XSalsa20 (согласно спецификации DNSCrypt, дополняется байтами со значением 0). Можно использовать тот или иной счётчик, “Яндекс.Браузер” так и поступает: cудя по всему, здесь передаётся 64-битное значение миллисекундного таймстемпа (время формирования запроса), к которому дописываются четыре байта псевдослучайных значений. На случай, если это действительно точное время, передаваемое в открытом виде, отмечу, что параметры дрейфа системных часов служат неплохим признаком, идентифицирующим конкретное аппаратное устройство, – то есть, могут быть использованы для деанонимизации;
Последнее поле – это сам зашифрованный запрос. Для шифрования используется общий секретный ключ, который вычисляется сторонами на основании переданных открытых ключей. В случае с клиентом – открытый ключ передаётся в пакете DNS-запроса (см. выше). “Яндекс.Браузер” следует стандартной практике и генерирует новую пару ключей (открытый/секретный) для X25119-hsalsa20 при каждом старте барузера. Для выравнивания данных на границу 64-байтового блока, как предписывает спецификация, используется стандартное дополнение (ISO/IEC 7816-4: 0x80 и нулевые байты в требуемом количестве).

Блок зашифрованных данных – это, скорее всего, результат использования функции crypto_box из библиотеки libsodium (либо NaCl, на которую ссылается спецификация DNSCrypt; libsodium – это форк NaCl). Я предположил, что 16-байтовый код аутентификации (MAC), который используется для проверки целостности сообщения перед расшифрованием, находится, вероятно, в начале блока. Впрочем, так как расшифровать данные я не пытался, то и определение расположения кода не столь важно. Для расшифрования можно использовать секретный ключ, который содержится в памяти во время работы браузера, но чтобы его извлечь – нужно некоторое время повозиться с отладчиком и дизассемблером.

Зашифрованный ответ, полученный от сервера:

DNSCrypt dump

(Нетрудно заметить, что ответ, представленный на скриншоте, поступил почти через пять секунд после запроса, почему так получилось – видимо, тема для отдельной записки.)

Пакет открывается magic, в данном случае, это байты, содержащие маркер ответа DNSCrypt (опять же, хорошая сигнатура для обнаружения трафика). Эти байты определены протоколом и должны присутствовать в начале всякого ответа сервера на запрос DNS-резолвинга;
Следующее поле – nonce (Response nonce). Поле содержит значение nonce, использованное сервером при шифровании данного ответа. Поле строится из двух равных частей, по 12 байтов: nonce из соответствующего клиентского запроса и серверное дополнение;
Заключительная часть пакета – зашифрованные данные ответа, формат аналогичен запросу.

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

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



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

Некоторое время назад выяснилось, что в Symasntec выпустили для Blue Coat промежуточный сертификат УЦ, который мог быть использован в SSL-прокси (для систем инспектирования трафика) – этот момент вызвал довольно живое обсуждение, так как прозрачный перехват TLS остаётся горячей темой в сообществе разработчиков браузеров. Следующее событие про эти две компании: Symantec покупает Blue Coat.



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

Продолжение реализации шифра “Кузнечик” (ГОСТ Р 34.12-2015) на языке Go. Я заменил в предыдущей реализации побайтовые XOR на 64-битные, это дало прирост производительности примерно в семь раз. Кроме того, я довольно существенно изменил код, дописав функции, реализующие операции шифрования/расшифрования с уже развёрнутыми наборами ключей – это необходимо для использования шифра в потоковом режиме.

Собственно, основной задачей было прицепить к “Кузнечику” режим GCM. Дело в том, что реализация работы с отдельными блоками сама по себе ничего не даёт, так как использовать шифр в таком режиме нельзя на практике (ну, разве что в роли генератора псевдослучайных чисел). Режим GCM – современный режим шифрования. Его, например, скорее всего использует ваш браузер, когда получает страницы dxdt.ru. Правда, браузер использует GCM в связке с AES. Но GCM совместим с любым блочным шифром подходящей разрядности. “Кузнечик” имеет разрядность блока 128 бит, так что он как раз подходит: достаточно взять реализацию GCM и подключить к ней “Кузнечик” в качестве шифра. В Go есть штатная реализация GCM. Поэтому мне оставалось только дописать интерфейсы к модулю “Кузнечика”, чтобы он оказался совместим со штатной реализацией GCM. Что получилось:

Небольшая справка: GCM – Galois/Counter Mode – режим счётчика с аутентификацией Галуа: это режим аутентифицированного шифрования, который, к тому же, поддерживает аутентификацию дополнительных данных (передаются в открытом виде). В англоязычной литературе это называется AEAD – Authenticated Encryption with Associated Data. В ГОСТовой криптографии такого режима как раз не хватает. Аутентифицированное шифрование позволяет обнаружить изменения сообщения до его расшифрования, для этого сообщение снабжается специальным кодом аутентификации (в русскоязычной традиции также называется имитовставкой). GCM позволяет защитить кодом аутентификации не только шифрованную часть сообщения, но и произвольные прикреплённые данные – это полезно, потому что в этих данных может быть записан, например, адрес получателя или другая открытая информация, которую, вместе с тем, требуется защитить от искажений/подмены. Я планирую как-нибудь написать в подробностях про шифры и режимы шифрования, в том числе, про GCM, скорее всего, в рамках дополнения к описанию TLS.

(Отдельно замечу, что данная реализация “Кузнечика” является лишь примером возможного использования данного шифра. Зато в режиме GCM можно, так сказать, полноценно шифровать большие файлы.)

Англоязычное пояснение:

This is the next implementation of GOST R 34.12-2015 Kuznyechik cipher in Golang. With optimized XOR and some other improvements the performance is about seven times better. Also it is now possible to use GOST R 34.12 package with crypto/cipher, particularly in GCM operation mode. New code has new name – kuznec.go. More comments – in Go source code for Kuznyechik (and see links in Russian text above).



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

Недавно очередной раз опубликовали базу аккаунтов “ВКонтакте”, по которой построили распределение паролей по частоте использования. Результат там вполне предсказуемый, лидирует что-то вроде “123456”. Интересно другое. Немалое число людей, публикующих эту статистику, делают вывод, что всё плохо с безопасностью у пользователей, и дают советы и рекомендациями о том, как же нужно выбирать “неугадываемый” пароль, чтобы, мол, не оказаться в “верхушке данного списка”. Да, у пользователей с безопасностью плохо, а пароли нужно выбирать стойкие. Эти банальные советы, в данном контексте, выглядят особенно забавно. Посудите сами: причиной для раздачи советов является статистика, построенная по базе, где пароли уже содержатся в открытом виде. И какая разница, насколько “неугадываемый” пароль вы выбрали, если через два дня этот пароль будет опубликован вместе с остальными данными аккаунта, утекшими от провайдера сервиса?



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