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

на главную - закладки

Жанры

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

Виега Джон

Шрифт:

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

Искупление греха

Как правило, мы рекомендуем применять системный CRNG–генератор. Есть лишь три исключения из этого правила: когда вы пишете программу для системы, в которой такого генератора нет; когда

имеется необходимость повторно воспроизвести поток случайных чисел и когда степень безопасности, гарантируемая системой, вас не устраивает (в частности, когда генерируются 192–или 256–битовые ключи в Windows с помощью стандартного криптографического провайдера).

Windows

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

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

...

#include <wincrypt.h>

void GetRandomBytes(BYTE *pbBuffer, DWORD dwLen) {

HCRYPTPROV hProvider; /* Вы должны создать экземпляр провайдера */

if (!CryptAcquireContext(&hProvider, 0, 0, PROV_RSA_FULL,

CRYPT_VERIFYCONTEXT))

ExitProcess((UINT) -1);

if (!CryptGetRandom(hProvider, dwLen, pbBuffer))

ExitProcess((UINT) -1);

}

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

Код для .NET

Чем пользоваться безнадежно предсказуемым классом Random, рекомендуем поступить таким образом:

using System.Security.Cryptography;

...

try {

byte[] b = new byte[32];

new RNGCryptoServiceProvider.GetBytes(b);

// b содержит 32 байта случайных данных

} catch (CryptographyException e) {

// Ошибка

}

Или на VB.NET:

...

Imports System.Security.Cryptography;

Dim b(32) As Byte

Dim i As Short

Try

Dim r As new RNGCryptoServiceProvider

r.GetBytes

\' b содержит 32 байта случайных данных

Catch e As CryptographyException

\' Обработать ошибку

End Try

Unix

В системах Unix криптографический генератор случайных чисел работает так же, как файл. Случайные числа поставляются двумя специальными устройствами (обычно они называются /dev/random и /dev/urandom, но в OpenBSD это /dev/ srandom и /dev/urandom). Реализации отличаются, но характеристики более–менее схожи. Эти устройства устроены так, что позволяют получать ключи любого разумного размера, поскольку хранят некий очень большой «ключ», содержащий, как правило, гораздо больше 256 битов энтропии. Как и в Windows, эти генераторы часто меняют затравку, в которую включаются все интересные асинхронные события, к примеру перемещения мыши и нажатия на клавиши.

Разница между /dev/random и /dev/urandom довольно тонкая. Может возникнуть мысль,

что первое – это интерфейс к истинно случайным числам, а второе – CRNG–генератор. Возможно, таково и было первоначальное намерение, но ни в какой реальной ОС оно не реализовано. На самом деле оба устройства–CRNG–генераторы. Более того, по существу, это один и тот же генератор. Единственная разница в том, что в /dev/random применяется некая метрика, позволяющая определить, есть ли опасность недостаточной энтропии. Метрика консервативна, и это, наверное, хорошо. Но на самом деле она настолько консервативна, что система может оказаться уязвимой для DoS–атак, особенно на серверах, где за консолью никто не сидит. Если у вас нет серьезных оснований полагать, что в системном CRNG–генераторе с самого начала не было ни одного непредсказуемого состояния, то пользоваться устройством /dev/random вообще не стоит. Мы рекомендуем работать только с /dev/urandom.

Доступ к генератору аналогичен доступу к любому файлу. Например, в 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);

...
Поделиться:
Популярные книги

Идеальный мир для Лекаря 21

Сапфир Олег
21. Лекарь
Фантастика:
фэнтези
юмористическое фэнтези
аниме
5.00
рейтинг книги
Идеальный мир для Лекаря 21

Книга пяти колец. Том 4

Зайцев Константин
4. Книга пяти колец
Фантастика:
фэнтези
попаданцы
5.00
рейтинг книги
Книга пяти колец. Том 4

Не отпускаю

Шагаева Наталья
Любовные романы:
современные любовные романы
эро литература
8.44
рейтинг книги
Не отпускаю

Брак по-драконьи

Ардова Алиса
Фантастика:
фэнтези
8.60
рейтинг книги
Брак по-драконьи

Князь

Мазин Александр Владимирович
3. Варяг
Фантастика:
альтернативная история
9.15
рейтинг книги
Князь

Столичный доктор

Вязовский Алексей
1. Столичный доктор
Фантастика:
попаданцы
альтернативная история
8.00
рейтинг книги
Столичный доктор

Камень. Книга 4

Минин Станислав
4. Камень
Фантастика:
боевая фантастика
7.77
рейтинг книги
Камень. Книга 4

Темный Охотник 2

Розальев Андрей
2. Темный охотник
Фантастика:
попаданцы
аниме
5.00
рейтинг книги
Темный Охотник 2

Измена. Не прощу

Леманн Анастасия
1. Измены
Любовные романы:
современные любовные романы
4.00
рейтинг книги
Измена. Не прощу

Перерождение

Жгулёв Пётр Николаевич
9. Real-Rpg
Фантастика:
фэнтези
рпг
5.00
рейтинг книги
Перерождение

Право налево

Зика Натаэль
Любовные романы:
современные любовные романы
8.38
рейтинг книги
Право налево

Истребители. Трилогия

Поселягин Владимир Геннадьевич
Фантастика:
альтернативная история
7.30
рейтинг книги
Истребители. Трилогия

Барон меняет правила

Ренгач Евгений
2. Закон сильного
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Барон меняет правила

Мастер 7

Чащин Валерий
7. Мастер
Фантастика:
фэнтези
боевая фантастика
попаданцы
технофэнтези
аниме
5.00
рейтинг книги
Мастер 7