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

ЖАНРЫ

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

Виега Джон

Шрифт:

Доступ к генератору аналогичен доступу к любому файлу. Например, в Python это делается так:

...

f = open(\'/dev/urandom\') # Если возникнет ошибка, будет возбуждено

# исключение.

data = f.read(128); # Прочитать 128 случайных байтов и сохранить их

# в data

Впрочем, функция os.urandom в Python предоставляет единый интерфейс к CRNG–генератору. В случае UNIX она обращается к нужному устройству, а в Windows вызывает CryptGetRandom.

Java

Как и в Windows, в языке Java реализована архитектура

на основе провайдеров. Различные провайдеры могут реализовывать предоставляемый Java API для получения случайных чисел криптографического качества и даже возвращать через тот же API необработанную энтропию. В реальности, однако, вы, скорее всего, будете работать с провайдером по умолчанию. А в большинстве реализации виртуальной Java–машины (JVM) провайдер по умолчанию почему–то получает энтропию собственными средствами, не обращаясь к системному CRNG–генератору. Поскольку JVM не встроена в операционную систему, она не является лучшим местом для сбора такого рода данных; в результате на получение первого числа может уйти заметное время (несколько секунд). Хуже того, Java делает это при запуске каждого нового приложения.

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

Класс SecureRandom предоставляет удобный API для доступа к генератору. Вы можете получить массив случайных байтов (nextBytes), случайное значение типа Boolean (nextBoolean), типа Double (nextDouble), типа Float (nextFloat), типа Int (nextlnt) или типа Long (nextLong). Можно также получить случайную величину с гауссовским (nextGaussian), а не равномерным распределением.

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

...

import java.security.SecureRandom;

...

byte test[20];

SecureRandom crng = new SecureRandom;

crng.nextBytes(test);

...

Повторное воспроизведение потока случайных чисел

Если по какой–то странной причине (например, для моделирования методом Монте Карло) вы захотите воспользоваться генератором случайных чисел, так чтобы можно было сохранить затравку, а затем воспроизвести весь поток, то получите исходную затравку от системного генератора, а затем используйте ее в качестве ключа для вашего любимого блочного шифра (например, AES). Рассматривайте 128–битовые входные данные для AES как одно 128–разрядное число. Начните с 0. Получите на выходе 16 байтов, зашифровав это значение. Когда понадобятся следующие данные, увеличьте значение на 1 и снова зашифруйте его. Можете продолжать это до бесконечности. Получить 400 000–ый байт в потоке? Нет ничего проще. (Кстати, для традиционных генераторов псевдослучайных чисел это совсем не так.)

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

счетчика.

Дополнительные защитные меры

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

Другие ресурсы

□ Стандарт NIST FIPS 140 содержит рекомендации относительно случайных чисел, прежде всего проверки их качества. Сейчас выпущена вторая редакция стандарта: FIPS 140–2. В тексте первой редакции процедура тестирования случайных чисел была описана более детально, так что есть смысл ознакомиться с ней: http://csrc.nist.gov/cryptval/140–2.htm

□ Система сбора и распределения энтропии (EGADS – Entropy Gathering AND Distribution System) предназначена главным образом для систем, не имеющих собственного CRNG–генератора и механизма сбора энтропии: www.securesoftware.com/resources/download_egads.html

□ RFC 1750: рекомендации по обеспечению случайности в целях безопасности: www.ietf.org/rfc/rfcl750.txt

□ «How We Learned to Cheat at Online Poker» by Brad Arkin, Frank Hill, Scott Marks, Matt Schmid, Thomas John Walls, and Gary McGraw: www.cigital.om/ papers/download/developer_gambling.pdf

□ «Randomness and Netscape Browser» by Ian Goldberg and David Wagner: www.ddj.com/documents/s=965/ddj9601h/9601h.htm

Резюме

Рекомендуется

□ По возможности пользуйтесь криптографическим генератором псевдослучайных чисел (CRNG).

□ Убедитесь, что затравка любого криптографического генератора содержит по меньшей мере 64, а лучше 128 битов энропии.

Не рекомендуется

□ Не пользуйтесь некриптографическими генераторами псевдослучайных чисел (некриптографические PRNG).

Стоит подумать

О том, чтобы в ситуациях, требующих повышенной безопасности, применять аппаратные генераторы псевдослучайных чисел.

Грех 19. Неудобный интерфейс

В чем состоит грех

Несколько лет назад инженеры из Центра проблем безопасности Microsoft (Microsoft Security Response Center – MSRC) сформулировали 10 незыблемых законов безопасного администрирования. Второй закон звучит так:

Система безопасности работает только тогда, когда безопасный способ одновременно является простым.

Ссылку на 10 незыблемых законов вы найдете в разделе «Другие ресурсы».

Безопасность и простота часто конфликтуют. Пароли – это один из популярных «простых» способов, но безопасным его обычно не назовешь (см. грех 11).

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

Подверженные греху языки

Эта проблема не связана ни с каким конкретным языком.

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