Генератор случайных чисел с использованием RANDOM.ORG
Генератор случайных чисел с использованием RANDOM.ORG
Тема генераторов случайных чисел является одной из основных в криптографии. Использование любых программных генераторов случайных чисел имеет один главный недостаток: последовательность чисел может называться случайной только если между символами, нету зависимости. А любой алгоритм так или иначе подразумевает зависимость от вычислений. Истинно случайные числа получаются только от аппаратных генераторов. Одним из таких генераторов является сайт RANDOM.ORG. По заявлению его владельцев, источником для случайных чисел является атмосферный шум. Не берусь утверждать, так это или нет, но этот сайт пользуется заслуженной популярностью среди разработчиков всего мира.
Для доступа к генератору на сайте есть API с подробной документацией. Доступ бесплатный, но есть ограничения на количество переданной информации. Причем ограничение определяется количеством бит, переданных на один ip в сутки. Как только лимит будет исчерпан, ничего получить с сайта будет нельзя. Покупку дополнительных бит я тут не рассматриваю, но она есть. Количество оставшихся бит также можно посмотреть через API. Впрочем, лимит этот большой (1.000.000 бит в сутки на один ip с ежедневным восстановлением 200.000 бит), и для обычного приложения его более чем достаточно.
С теорией закончили, перейдем к практической реализации. Я написал две функции для проверки количества оставшихся бит и для получения истинно случайных чисел с сайта RANDOM.ORG. Начну с функции проверки лимита. Она самодостаточная, не требует никаких дополнительных данных. Возвращает количество оставшихся бит для текущего ip-адреса или 0, если сайт недоступен или лимит исчерпан.
Code (Assembler) : Убрать нумерацию
- ;----------------------------------------------------------------
- ; Проверка количества оставшихся бесплатных бит,
- ; а также доступности сайта RANDOM.ORG
- ;----------------------------------------------------------------
- ; На выходе:
- ; EAX = 0 - сайт недоступен или бесплатных бит не осталось
- ; EAX > 0 - количество оставшихся бит
- ;----------------------------------------------------------------
- proc RO_chk_bits
- locals
- result dd ?
- tmp dd ?
- bits rb 100h
- endl
- ; Сохранить все регистры
- pusha
- ; По умолчанию все плохо
- mov [result],0
- ; Открыть соединение
- invoke InternetOpen,NULL,INTERNET_OPEN_TYPE_PRECONFIG,NULL,NULL,0
- or eax,eax
- jz .loc_ret
- ; Положить Handle на стек
- push eax
- ; Запросить соединение с URL
- invoke InternetOpenUrl,eax,.q_link,NULL,0,INTERNET_FLAG_NO_UI,0
- or eax,eax
- jz .loc_close_hinet
- mov ebx,eax
- ; Прочитать количество оставшихся бит
- lea esi,[bits]
- lea edi,[tmp]
- invoke InternetReadFile,eax,esi,100h,edi
- or eax,eax
- jz .loc_close_hconnection
- ; Перевести строку в число
- ; Отрицательное значение будет приравнено к 0
- lea esi,[bits]
- stdcall str2dec,esi
- mov [result],eax
- .loc_close_hconnection:
- invoke InternetCloseHandle,ebx
- .loc_close_hinet:
- ; Handle на стеке
- invoke InternetCloseHandle
- .loc_ret:
- ; Восстановить все регистры
- popa
- ; Вернуть результат в EAX
- mov eax,[result]
- ret
- .q_link db 'https://www.random.org/quota/?format=plain',0
- endp
Code (Assembler) : Убрать нумерацию
- ;----------------------------------------------------------------
- ; Получение случайных чисел с сайта RANDOM.ORG
- ;----------------------------------------------------------------
- ; Параметры:
- ; dNum - количество получаемых случайных чисел
- ; dMin - нижняя граница интервала
- ; dMax - верхняя граница интервала
- ; lpBuff - указатель на буфер-приемник для полученных данных
- ;----------------------------------------------------------------
- ; На выходе:
- ; EAX = 0 - случайные числа получить не удалось
- ; EAX = 1 - функция отработала правильно
- ;----------------------------------------------------------------
- proc RO_get_random dNum:DWORD, dMin:DWORD, dMax:DWORD, lpBuff:DWORD
- locals
- result dd ?
- tmp dd ?
- link rb 100h
- endl
- ; Сохранить все регистры
- pusha
- ; По умолчанию все плохо
- mov [result],0
- ; Сколько чисел запросить (не менее 1)
- cmp [dNum],1
- jb .loc_ret
- ; Проверить границы случайных чисел
- mov eax,[dMin]
- cmp eax,[dMax]
- jae .loc_ret
- ; Проверить количество оставшихся бит
- stdcall RO_chk_bits
- or eax,eax
- jz .loc_ret
- lea esi,[link]
- invoke wsprintf,esi,.r_link,[dNum],[dMin],[dMax]
- add esp,20
- ; Открыть соединение
- invoke InternetOpen,NULL,INTERNET_OPEN_TYPE_PRECONFIG,NULL,NULL,0
- or eax,eax
- jz .loc_ret
- ; Положить Handle на стек
- push eax
- lea esi,[link]
- ; Запросить соединение с URL
- invoke InternetOpenUrl,eax,esi,NULL,0,INTERNET_FLAG_NO_UI,0
- or eax,eax
- jz .loc_close_hinet
- mov ebx,eax
- mov ecx,[dNum]
- shl ecx,2
- cmp [dNum],100
- jb @f
- shl ecx,1
- cmp [dNum],100000
- jb @f
- shl ecx,1
- @@:
- lea edi,[tmp]
- invoke InternetReadFile,eax,[lpBuff],ecx,edi
- or eax,eax
- jz .loc_close_hconnection
- mov [result],eax
- .loc_close_hconnection:
- invoke InternetCloseHandle,ebx
- .loc_close_hinet:
- ; Handle на стеке
- invoke InternetCloseHandle
- .loc_ret:
- ; Восстановить все регистры
- popa
- ; Вернуть результат в EAX
- mov eax,[result]
- ret
- .r_link db 'https://www.random.org/integers/'
- db '?num=%u&min=%u&max=%u&col=1&base=10&format=plain&rnd=new',0
- endp
Code (Assembler) : Убрать нумерацию
- ;----------------------------------------------------------
- ; На входе: указатель на строку
- ; На выходе: EAX = число или 0 если не получилось
- ;----------------------------------------------------------
- proc str2dec lpStr:dword
- push ebx edx esi
- xor eax,eax
- mov esi,[lpStr]
- .str2dec_loop:
- movsx ebx,byte [esi]
- sub bl,'0'
- cmp bl,10
- jnb .str2dec_ret
- imul eax,10
- add eax,ebx
- inc esi
- jmp .str2dec_loop
- .str2dec_ret:
- pop esi edx ebx
- ret
- endp
Просмотров: 3789 | Комментариев: 11
Метки: Assembler, генератор ПСЧ
Внимание! Статья опубликована больше года назад, информация могла устареть!
Комментарии
Отзывы посетителей сайта о статье
ManHunter
(23.08.2018 в 18:50):
Интересная история сервиса Random.org : https://habr.com/company/ruvds/blog/421031/
ManHunter
(10.11.2016 в 17:28):
Вот когда возникнет необходимость генерить действительно случайные числа в промышленных масштабах, на серверной стороне и в максимально короткие промежутки времени, тогда я бы еще раз и с особым интересом выслушал мнение настоящих параноиков о неиссякаемых источниках их получения.
Андрей
(28.10.2016 в 23:11):
Настоящий параноик смеётся с ваших непонятно на чём сделаных генераторов и неизвестно чьих сертификатов. Тем более что современный компьютер просто набит бесплатными рандомами. позиция мыши, время работы машины после включения, пинг до сайта, интервалы времени между нажатий клавиш, картинка с вебкамеры. Только успевай грести.
ManHunter
(28.10.2016 в 12:41):
Для параноиков есть аппаратные генераторы: http://www.idquantique.com/ran...r-generator/
С сертификатами, результатами официальных тестов и т.п.
С сертификатами, результатами официальных тестов и т.п.
ЖК
(28.10.2016 в 02:50):
Как ассемблерный пример получения инфы с заданного сайта - хорошо.
Что касается качества рандомных значений - тут уж каждый чешет свою паранойю сам. На мой взгляд, банальные rdrand из Ivy Bridge+ или rdseed из Broadwell+ как минимум не менее безопасны, чем некое (непонятно как на самом деле полученное) значение с произвольного интернет-сайта.
Что касается качества рандомных значений - тут уж каждый чешет свою паранойю сам. На мой взгляд, банальные rdrand из Ivy Bridge+ или rdseed из Broadwell+ как минимум не менее безопасны, чем некое (непонятно как на самом деле полученное) значение с произвольного интернет-сайта.
ManHunter
(26.10.2016 в 23:58):
Да, надо было добавить WS_VSCROLL+WS_HSCROLL. Под мое DPI отобразилось нормально, я и успокоился.
Андрей
(26.10.2016 в 23:54):
Мгы гы. С подарком вышло как в том анекдоте про почту и шарфик. Долго шарил по коду, на предмет почему вместо обещанных 20 цифр выводит только 19. Но потом подрастянул 'EDIT' до 190 и вуаля.
ManHunter
(26.10.2016 в 22:52):
"Мое дело подарок подарить, а ты уж думай, что с этой хренью делать" (с) Масяня
Андрей
(26.10.2016 в 22:41):
Абсурд ситуации заключается в следующем, допустим ты кладешь ценную вещь в камеру хранения. И тебе нужен код для замка. Но мотивируя тем, что сам ты его придумать не сможешь (память услужливо подсовывает даты рождения свою и близких, номера машины, квартиры, телефона). Поэтому ты не находишь ничего лучше как обратится к охраннику вокзала с просьбой сказать наобум несколько цифр.
Уязвимостей в этой схеме сразу несколько
1. Канал связи. Вас могут подслушать.
2. Заинтересованность третьих лиц. Кто мешает охраннику за долю малую сливать подсмотренные коды вокзальным жуликам.
3. Отсутствие твёрдых гарантий того что выданное охранником число истинно случайно.У него есть тоже машина, квартира и дни рождения родных и близких. Ну это аллюзия к "атмосферному шуму" которому ни что не мешает содержать в себе всё те же не инициализированные обрывки данных надёрганные из эфира.
Это если смотреть на безопасность совсем по взрослому.
Уязвимостей в этой схеме сразу несколько
1. Канал связи. Вас могут подслушать.
2. Заинтересованность третьих лиц. Кто мешает охраннику за долю малую сливать подсмотренные коды вокзальным жуликам.
3. Отсутствие твёрдых гарантий того что выданное охранником число истинно случайно.У него есть тоже машина, квартира и дни рождения родных и близких. Ну это аллюзия к "атмосферному шуму" которому ни что не мешает содержать в себе всё те же не инициализированные обрывки данных надёрганные из эфира.
Это если смотреть на безопасность совсем по взрослому.
ManHunter
(26.10.2016 в 22:00):
Это лучше, чем отреверсенный алгоритм генерации с предсказуемой и гарантированно воспроизводимой последовательностью.
Андрей
(26.10.2016 в 21:37):
С точки зрения безопасности случайная последовательность предоставленная кем то это тот же пресловутый ключ от входной двери хранящийся под ковриком.
Добавить комментарий
Заполните форму для добавления комментария