Анимация
JavaScript


Главная  Библионтека 

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 [ 17 ]

является в некоторой мере чем-то непредсказуемхм. */

void churnrand(char *randevent,unsigned Int randlen) { MD5 CTX md5; MD5Init(&md5);

MD5Update(&md5, Randpool , sizeof(Randpool)); MD5Update(&md5 , randevent , randlen ); MD5Final(Randpool,&md5);

После достаточных вызовов chumrand() накопления достаточной случайности в Randpool, можно генерировать из этого случайные биты. MD5 снова становится полезной, в этот раз в качестве генератора псевдослуча й-ного байтового потока, работающего в режиме счетчика.

long Randcnt;

void genrand(char *buf,unsigned int buflen) { MD5 CTX md5; char tmp[16]; unsigned int n; while(buflen != 0) {

/* Пул хэшируется счетчиком */

MD5Init(&md5);

MD5Update(&md5, Randpool, sizeof(Randpool)); MD5Update(&md5,(unsigned char *)&Randcnt,sizeof(Randcnt)); MD5Final(tmp,&md5);

Randcnt++; /* Инкрементируем счетчик */

/Копируем 16 или запрошенное число байтов, если оно меньше 16, в буфер пользователя*/

n = (buflen < 16) ? buflen : 16; memcpy(buf, tmp, n); buf += n ; buflen -= n;

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

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

Но остается одна проблема. Прежде, чем в первый раз будет вызвана genrand() в массиве Randpool[] должно быть накоплено достаточно случайных данных . Если система какое-то время работала с локальным пользователем, что-то печатающим на клавиатуре, то проблем нет. Но как насчет независимой системы, которая перегр у-жается автоматически, не обращая внимания ни на какие данные клавиатуры или мыши ?

Но есть одна трудность. В качестве частичного решения можно потребовать, чтобы после самой первой з а-грузки оператор какое-то время поработал на клавиатуре и создал на диске стартовый файл перед выгрузкой операционной системы, чтобы в ходе перезагрузок использовались случайные данные, переданные в Randseed[]. Но не сохраняйте непосредственно сам Randseed[]. Взломщик, которому удастся заполучить этот файл, сможет определить все результаты genrand() после последнего обращения к chumrand() прежде, чем этот файл будет создан.

Решением этой проблемы является хэширование массива Randseed[] перед его сохранением, может даже вызовом genrandO. При перезагрузке системы вы считываете данные из стартового файла, передаете их



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



0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 [ 17 ]