Чтение онлайн

ЖАНРЫ

19 смертных грехов, угрожающих безопасности программ

Виега Джон

Шрифт:

Проблема в том, что противник не должен знать затравку. Чтобы CRNG–гене–ратор был безопасным, затравка должна быть неугадываемой, а это, как мы вскоре убедимся, непростая задача.

Таким образом, безопасность CRNG не может быть больше, чем безопасность затравки. Если у противника есть один шанс из 224 угадать затравку, значит, с такой же вероятностью он сможет предсказать поток вырабатываемых чисел. Следовательно, у системы есть только 24 бита безопасности, пусть даже лежащий в ее основе криптографический алгоритм обладает 128 битами безопасности. Задачу противника лишь немного осложняет тот факт, что он не знает, в каком месте потока находится.

CRNG–генераторы часто считаются синонимами потоковых шифров. Технически это правильно. Например, RC4 – это потоковый шифр, который порождает строку случайных битов, которую можно объединить с

помощью операции XOR с открытым текстом. Или использовать непосредственно, и тогда мы получим CRNG–генератор.

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

Следует также отметить, что стойкость криптографического генератора не может быть выше стойкости ключа. Например, если вы хотите генерировать 256–битовые ключи для шифра AES, поскольку ключ длиной 128 битов кажется вам недостаточным, то не стоит в качестве генератора случайных чисел использовать шифр RC4. Мало того, что RC4 обычно генерирует 128–битовые ключи, так еще и эффективная стойкость этих ключей составляет всего 30 битов.

В состав большинства современных операционных систем уже входит тот или иной CRNG–генератор. Кроме того, они умеют получать истинно случайные числа, так что умение создавать собственные алгоритмы для этой цели уже не так важно.

Греховность генераторов истинно случайных чисел

Если CRNG–генератору все равно нужны для работы истинно случайные числа и если вы не занимаетесь испытаниями по методу Монте Карло, которые должны быть воспроизводимы, то почему бы просто не обратиться к генераторам истинно случайных чисел?

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

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

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

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

Родственные грехи

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

Где искать ошибку

Этот грех может проявиться в любой ситуации, когда нужно хранить некоторые данные в секрете, не допуская даже случайного

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

Выявление ошибки на этапе анализа кода

Шагов не так много:

□ выявить места, в которых следовало бы пользоваться случайными числами, но это не делается;

□ выявить места, где применяются PRNG–генераторы;

□ убедиться, что для всех применяемых CRNG–генераторов используется затравка надлежащего качества.

Когда следует использовать случайные числа

Задача выявления всех мест, где надо было бы применить случайные числа, но это не сделано, может оказаться очень трудной. Для ее решения нужно понимать, какими данными манипулирует программа, а часто еще и детально разбираться в используемых библиотеках. Например, старые криптографические библиотеки ожидают, что затравку CRNG–генератору вы зададите самостоятельно. В первых версиях библиотека продолжала работать, даже если вы никакую затравку не задали. Позже в этом случае стали возвращать сообщение об ошибке (или вообще завершать программу). Но вошло в привычку задавать в качестве затравки фиксированное значение, чтобы заставить библиотеку «заткнуться». В наше дни практически все криптографические библиотеки получают затравку непосредственно от системы.

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

Выявление мест, где применяются PRNG–генераторы

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

Как правило, те, кто использует некриптографический PRNG–генератор, обращаются к API, поставляемому вместе с языком программирования, поскольку не знают ничего лучшего. В табл. 18.1 перечислены некоторые из стандартных библиотечных функций.

Для CRNG–генераторов редко существует стандартный API, разве что его предоставляет используемая криптографическая библиотека. Если это так, можете пользоваться им, обычно это безопасно.

Есть несколько стандартных подходов. Сейчас криптографы отдают предпочтение блочным шифрам (обычно AES) в режиме счетчика. Еще один популярный генератор описан в стандарте ANSI Х9.17. Столкнувшись с любым из них, ищите все случаи употребления симметричной криптографии и самостоятельно попытайтесь определить, корректно ли генератор реализован и хорошо ли затравлен.

Таблица 18.1. Некриптографические генераторы псевдослучайных чисел в популярных языках

Правильно ли затравлен CRNG–генератор

Если затравку для CRNG–генератора формирует система, то риска, скорее всего, нет. Но в языке типа Java, где API не пользуется системным генератором или не задействует CRNG напрямую, у вас может быть возможность задать затравку самостоятельно. И этим часто пользуются хотя бы для того, чтобы ускорить инициализацию. (В Java это случается часто, поскольку инициализация класса SecureRan–dom происходит довольно медленно; см. раздел «Java» ниже в этой главе.)

Есть и другая крайность – когда затравка фиксирована. В таком случае систему следует считать небезопасной. Если затравка хранится в файле и периодически обновляется значением, которое выработано генератором, то безопасность зависит от того, насколько хороша была первоначальная затравка и насколько надежно защищен файл.

Если используется код для получения энтропии сторонней фирмы, то степень риска определить сложно. (Теория энтропии находится за рамками данной книги.) Хотя в таких случаях риск может быть невелик, все же, если есть возможность воспользоваться системным генератором, мы рекомендуем так и поступить.

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

Поделиться с друзьями: