Найти тему

Криптоалгоритмы в руках поколения ЕГЭ

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

Итак, каков алгоритм действий здорового человека? Сначала опишу техническим языком.

1) Приложение генерирует сообщения для последующего подписания клиентом (набор бессмысленных символов) и отправляет его клиенту.
2) Клиент данное сообщение подписывает своим сертификатом и отправляет подписанное сообщение назад в приложение.
3) Приложение на основании полученных данных получает открытые данные сертификата клиента и на основании этих данных принимает решение о дальнейшей судьбе клиента.

Теперь опишу попроще. Я отправляю клиенту некий документ на подпись. Клиент подписывает мой документ и отправляет обратно. Я проверяю полученный документ и принимаю решение - что делать с клиентом. Казалось бы, что может быть проще? А, оказывается, бывает и немножко по- другому.

Пример 1. Или скрытая угроза. Все происходит ровно по тому сценарию, что я описал с одним важным упущением. Приложение никуда не сохраняет придуманную последовательность символов. Клиентская часть приложения, которую пишем, конечно же, мы сами получает данную последовательность, подписывает и отправляет обратно. Все шикарно, все работает. С одной досадной оговоркой – а что будет, если клиентская часть подпишет другую последовательность? Да ничего не будет. Логика отработает штатно. И клиент подменивший последовательность также получит доступ. Как и любой другой человек, включая того кто случайно получил/подглядел доступ к телу запроса. Ой, а вот и уязвимость. Идея всего процесса в проверке наличия доступа к закрытой части электронной подписи, но вот такой вот пустячок открывает безграничные возможности для хакинга различной степени этичности. Метод борьбы очевиден – ВСЕГДА проверять исходное сообщение.

Пример 2. Или мы доверяем своим клиентам. Фактически это оптимизация пункта 1. Разработчик, увидевший код из примера 1 видит очевиднейший путь оптимизации. А зачем нам придумывать что-либо если мы не проверяем корректность исходного сообщения, и клиент может слать что попало? И действительно – давайте просто проверять сообщение и подписанное сообщение. По факту – здесь просто проверяется, что кто-то когда-то имел доступ к закрытой части сертификата для подписания. Но потенциальная уязвимость на месте. Методы борьбы чуть менее очевидны – вообще то метод может быть вполне рабочим, необходимо жестко ограничить формат подписанных сообщений. Например, если подписывать текущую дату с точностью до 30 минут – вы получите комбинацию, которая будет валидна не более 30 минут.

Пример 3. Или «как выглядит безумие». Приложение вполне может хранить данные об открытой части клиентского сертификата. На то она и открытая. Предположим у нас есть внутренний сервис, который по отпечатку сертификата дает подробные данные о его владельце. Подчеркну – ВНУТРЕННИЙ сервис. Но какому-то сумрачному гению пришло в голову дать доступ к такому сервису клиенту. Самое интересное – работать будет прекрасно. Просто сказать что это небезопасно, это не сказать ничего. Методы борьбы? Да какие тут могут быть методы. Только термический криптоанализатор в применении к автору. Эта практика по определению не может быть применима.

Кажется что я тут навыдумывал детских ошибок? Может быть. Но вот не напрягая мозг без проблем вспомню историю банка Тинькоф, который подписал кредитный договор не обращая внимания на то, что клиент его «чуть-чуть» поправил. Да и периодические истории о сливе данных различной степени важности говорит о том, что не все разработчики до конца понимают значение слова «безопасность».