Blog. Just Blog

Генератор случайных чисел с использованием RANDOM.ORG

Версия для печати Добавить в Избранное Отправить на E-Mail | Категория: Образ мышления: Assembler | Автор: ManHunter
Генератор случайных чисел с использованием RANDOM.ORG
Генератор случайных чисел с использованием RANDOM.ORG

Тема генераторов случайных чисел является одной из основных в криптографии. Использование любых программных генераторов случайных чисел имеет один главный недостаток: последовательность чисел может называться случайной только если между символами, нету зависимости. А любой алгоритм так или иначе подразумевает зависимость от вычислений. Истинно случайные числа получаются только от аппаратных генераторов. Одним из таких генераторов является сайт RANDOM.ORG. По заявлению его владельцев, источником для случайных чисел является атмосферный шум. Не берусь утверждать, так это или нет, но этот сайт пользуется заслуженной популярностью среди разработчиков всего мира.

Для доступа к генератору на сайте есть API с подробной документацией. Доступ бесплатный, но есть ограничения на количество переданной информации. Причем ограничение определяется количеством бит, переданных на один ip в сутки. Как только лимит будет исчерпан, ничего получить с сайта будет нельзя. Покупку дополнительных бит я тут не рассматриваю, но она есть. Количество оставшихся бит также можно посмотреть через API. Впрочем, лимит этот большой (1.000.000 бит в сутки на один ip с ежедневным восстановлением 200.000 бит), и для обычного приложения его более чем достаточно.

С теорией закончили, перейдем к практической реализации. Я написал две функции для проверки количества оставшихся бит и для получения истинно случайных чисел с сайта RANDOM.ORG. Начну с функции проверки лимита. Она самодостаточная, не требует никаких дополнительных данных. Возвращает количество оставшихся бит для текущего ip-адреса или 0, если сайт недоступен или лимит исчерпан.
  1. ;----------------------------------------------------------------
  2. ; Проверка количества оставшихся бесплатных бит,
  3. ; а также доступности сайта RANDOM.ORG
  4. ;----------------------------------------------------------------
  5. ; На выходе:
  6. ;   EAX = 0 - сайт недоступен или бесплатных бит не осталось
  7. ;   EAX > 0 - количество оставшихся бит
  8. ;----------------------------------------------------------------
  9. proc RO_chk_bits
  10.         locals
  11.             result  dd ?
  12.             tmp     dd ?
  13.             bits    rb 100h
  14.         endl
  15.  
  16.         ; Сохранить все регистры
  17.         pusha
  18.  
  19.         ; По умолчанию все плохо
  20.         mov     [result],0
  21.  
  22.         ; Открыть соединение
  23.         invoke  InternetOpen,NULL,INTERNET_OPEN_TYPE_PRECONFIG,NULL,NULL,0
  24.         or      eax,eax
  25.         jz      .loc_ret
  26.  
  27.         ; Положить Handle на стек
  28.         push    eax
  29.  
  30.         ; Запросить соединение с URL
  31.         invoke  InternetOpenUrl,eax,.q_link,NULL,0,INTERNET_FLAG_NO_UI,0
  32.         or      eax,eax
  33.         jz      .loc_close_hinet
  34.  
  35.         mov     ebx,eax
  36.  
  37.         ; Прочитать количество оставшихся бит
  38.         lea     esi,[bits]
  39.         lea     edi,[tmp]
  40.         invoke  InternetReadFile,eax,esi,100h,edi
  41.         or      eax,eax
  42.         jz      .loc_close_hconnection
  43.  
  44.         ; Перевести строку в число
  45.         ; Отрицательное значение будет приравнено к 0
  46.         lea     esi,[bits]
  47.         stdcall str2dec,esi
  48.         mov     [result],eax
  49.  
  50. .loc_close_hconnection:
  51.         invoke  InternetCloseHandle,ebx
  52.  
  53. .loc_close_hinet:
  54.         ; Handle на стеке
  55.         invoke  InternetCloseHandle
  56.  
  57. .loc_ret:
  58.         ; Восстановить все регистры
  59.         popa
  60.  
  61.         ; Вернуть результат в EAX
  62.         mov     eax,[result]
  63.         ret
  64.  
  65. .q_link db 'https://www.random.org/quota/?format=plain',0
  66.  
  67. endp
Функция получения случайных чисел также использует эту проверку, поэтому без необходимости дублировать вызовы не обязательно. Параметры вызова: dNum - количество получаемых случайных чисел, dMin - нижняя граница интервала, dMax - верхняя граница интервала, lpBuff - указатель на буфер-приемник для полученных данных. Есть особенности. Запросы на сервер занимают время, поэтому, если требуется получить сразу большое количество случайных чисел, то надо делать это одним запросом, а потом разбирать результат по мере надобности. Размер буфера для приема данных не проверяется, его надо резервировать с запасом, исходя из количества запрошенных случайных чисел и количества цифр в них. Случайные числа в возвращаемом результате разделены символов переноса строки 0Ah и заканчиваются нулевым значением.
  1. ;----------------------------------------------------------------
  2. ; Получение случайных чисел с сайта RANDOM.ORG
  3. ;----------------------------------------------------------------
  4. ; Параметры:
  5. ;   dNum - количество получаемых случайных чисел
  6. ;   dMin - нижняя граница интервала
  7. ;   dMax - верхняя граница интервала
  8. ;   lpBuff - указатель на буфер-приемник для полученных данных
  9. ;----------------------------------------------------------------
  10. ; На выходе:
  11. ;   EAX = 0 - случайные числа получить не удалось
  12. ;   EAX = 1 - функция отработала правильно
  13. ;----------------------------------------------------------------
  14. proc RO_get_random dNum:DWORD, dMin:DWORD, dMax:DWORD, lpBuff:DWORD
  15.         locals
  16.             result  dd ?
  17.             tmp     dd ?
  18.             link    rb 100h
  19.         endl
  20.  
  21.         ; Сохранить все регистры
  22.         pusha
  23.  
  24.         ; По умолчанию все плохо
  25.         mov     [result],0
  26.  
  27.         ; Сколько чисел запросить (не менее 1)
  28.         cmp     [dNum],1
  29.         jb      .loc_ret
  30.  
  31.         ; Проверить границы случайных чисел
  32.         mov     eax,[dMin]
  33.         cmp     eax,[dMax]
  34.         jae     .loc_ret
  35.  
  36.         ; Проверить количество оставшихся бит
  37.         stdcall RO_chk_bits
  38.         or      eax,eax
  39.         jz      .loc_ret
  40.  
  41.         lea     esi,[link]
  42.         invoke  wsprintf,esi,.r_link,[dNum],[dMin],[dMax]
  43.         add     esp,20
  44.  
  45.         ; Открыть соединение
  46.         invoke  InternetOpen,NULL,INTERNET_OPEN_TYPE_PRECONFIG,NULL,NULL,0
  47.         or      eax,eax
  48.         jz      .loc_ret
  49.  
  50.         ; Положить Handle на стек
  51.         push    eax
  52.  
  53.         lea     esi,[link]
  54.  
  55.         ; Запросить соединение с URL
  56.         invoke  InternetOpenUrl,eax,esi,NULL,0,INTERNET_FLAG_NO_UI,0
  57.         or      eax,eax
  58.         jz      .loc_close_hinet
  59.  
  60.         mov     ebx,eax
  61.  
  62.         mov     ecx,[dNum]
  63.         shl     ecx,2
  64.         cmp     [dNum],100
  65.         jb      @f
  66.         shl     ecx,1
  67.         cmp     [dNum],100000
  68.         jb      @f
  69.         shl     ecx,1
  70. @@:
  71.         lea     edi,[tmp]
  72.         invoke  InternetReadFile,eax,[lpBuff],ecx,edi
  73.         or      eax,eax
  74.         jz      .loc_close_hconnection
  75.  
  76.         mov     [result],eax
  77.  
  78. .loc_close_hconnection:
  79.         invoke  InternetCloseHandle,ebx
  80.  
  81. .loc_close_hinet:
  82.         ; Handle на стеке
  83.         invoke  InternetCloseHandle
  84.  
  85. .loc_ret:
  86.         ; Восстановить все регистры
  87.         popa
  88.  
  89.         ; Вернуть результат в EAX
  90.         mov     eax,[result]
  91.         ret
  92.  
  93. .r_link db 'https://www.random.org/integers/'
  94.         db '?num=%u&min=%u&max=%u&col=1&base=10&format=plain&rnd=new',0
  95. endp
Поскольку данные с сайта возвращаются только в текстовом виде, придется использовать вспомогательную функцию для перевода из текста в число:
  1. ;----------------------------------------------------------
  2. ; На входе: указатель на строку
  3. ; На выходе: EAX = число или 0 если не получилось
  4. ;----------------------------------------------------------
  5. proc    str2dec lpStr:dword
  6.         push    ebx edx esi
  7.  
  8.         xor     eax,eax
  9.         mov     esi,[lpStr]
  10. .str2dec_loop:
  11.         movsx   ebx,byte [esi]
  12.         sub     bl,'0'
  13.         cmp     bl,10
  14.         jnb     .str2dec_ret
  15.         imul    eax,10
  16.         add     eax,ebx
  17.         inc     esi
  18.         jmp     .str2dec_loop
  19. .str2dec_ret:
  20.         pop     esi edx ebx
  21.         ret
  22. endp
В приложении пример программы с исходным текстом, получающей с сайта RANDOM.ORG массив из 20 случайных чисел в интервале от 1 до 99. Также выводится количество оставшихся бесплатных бит.

Пример программы с исходным текстом (FASM)Пример программы с исходным текстом (FASM)

Random.org.Demo.zip (4,352 bytes)


Поделиться ссылкой ВКонтакте
Просмотров: 3679 | Комментариев: 11

Внимание! Статья опубликована больше года назад, информация могла устареть!

Комментарии

Отзывы посетителей сайта о статье
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+ как минимум не менее безопасны, чем некое (непонятно как на самом деле полученное) значение с произвольного интернет-сайта.
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. Отсутствие твёрдых гарантий того что выданное охранником число истинно случайно.У него есть тоже машина, квартира и дни рождения родных и близких. Ну это аллюзия к "атмосферному шуму" которому ни что не мешает содержать в себе всё те же не инициализированные обрывки данных надёрганные из эфира.

Это если смотреть на безопасность совсем по взрослому.
ManHunter (26.10.2016 в 22:00):
Это лучше, чем отреверсенный алгоритм генерации с предсказуемой и гарантированно воспроизводимой последовательностью.
Андрей (26.10.2016 в 21:37):
С точки зрения безопасности случайная последовательность предоставленная кем то это тот же пресловутый ключ от входной двери хранящийся под ковриком.

Добавить комментарий

Заполните форму для добавления комментария
Имя*:
Текст комментария (не более 2000 символов)*:

*Все поля обязательны для заполнения.
Комментарии, содержащие рекламу, ненормативную лексику, оскорбления и т.п., а также флуд и сообщения не по теме, будут удаляться. Нарушителям может быть заблокирован доступ к сайту.
Наверх
Powered by PCL's Speckled Band Engine 0.2 RC3
© ManHunter / PCL, 2008-2024
При использовании материалов ссылка на сайт обязательна
Время генерации: 0.06 сек. / MySQL: 2 (0.0055 сек.) / Память: 4.5 Mb
Наверх