- Генерация случайных байтов средствами OS.
- os.getrandom(size, flags=0) :
- os.urandom(size) :
- os.GRND_NONBLOCK :
- os.GRND_RANDOM :
- 5c0tt / random_number
- aweijnitz / urandom_music.sh
- os.urandom, CPython, Linux и грабли
- Are we using /dev/urandom on Mac OS and is that a bad idea? #594
- Comments
- NodeGuy commented Sep 10, 2017
Генерация случайных байтов средствами OS.
os.getrandom(size, flags=0) :
Функция os.getrandom() возвращает случайные байты до размера size . Функция может вернуть меньше байтов, чем запрошено.
Эти байты могут использоваться для заполнения генераторов случайных чисел в пространстве пользователя или для криптографических целей.
Функция os.getrandom() использует энтропию, полученную от драйверов устройств и других источников шума окружающей среды. Чрезмерное чтение больших объемов данных будет иметь негативное влияние на других пользователей устройств /dev/random и /dev/urandom .
Аргумент flags представляет собой битовую маску, которая может содержать ноль или более следующих значений ORed вместе: os.GRND_RANDOM и os.GRND_NONBLOCK .
Смотрите также страницу руководства Linux по getrandom() .
Доступность: Linux 3.17 и новее.
os.urandom(size) :
Функция os.urandom() возвращает строку случайных байтов размером size , пригодную для криптографического использования.
Эта функция возвращает случайные байты из специфичного для операционной системы источника случайности. Возвращаемые данные должны быть достаточно непредсказуемыми для криптографических приложений, хотя их точное качество зависит от реализации ОС.
В Linux, если доступна системный вызов getrandom() , то она используется в режиме блокировки: блокируется до инициализации системного пула энтропии urandom (ядро собирает 128 бит энтропии). В Linux функция os.getrandom() может использоваться для получения случайных байтов в неблокирующем режиме, используя флаг os.GRND_NONBLOCK или для опроса до тех пор, пока не будет инициализирован системный пул энтропии urandom .
В Unix-подобной системе случайные байты считываются с устройства /dev/urandom . Если устройство /dev/urandom недоступно или не читается, возникает исключение NotImplementedError .
В Windows он будет использовать системный вызов CryptGenRandom() .
- Смотрите также модуль secrets предоставляет функции более высокого уровня.
- Простой в использовании интерфейс генератора случайных чисел, предоставляемый вашей платформой random.SystemRandom .
os.GRND_NONBLOCK :
Значение os.GRND_NONBLOCK стоит по умолчанию при чтении из /dev/random блокирует os.getrandom() , если нет доступных случайных байтов, а при чтении из /dev/urandom блокируется, если пул энтропии еще не был инициализирован.
Если установлен флаг os.GRND_RANDOM , то os.getrandom() в этих случаях не блокируется, а немедленно вызывает исключение BlockingIOError .
os.GRND_RANDOM :
Если этот бит установлен, то случайные байты извлекаются из пула /dev/random вместо пула /dev/urandom .
Источник
5c0tt / random_number
# Make sure to `chmod u+x random_number` in order to make this file go |
#!/bin/bash |
# Generate random strings on Mac OS X |
# the `tr` uses a regex to decide which characters you want to include |
# This is very slow as a bash script, random seems faster than urandom |
# though I have been told that one just symblinks the other so that would |
# then not be possible to be faster. |
# Here is some sample output from the below: |
# 4o)lATvDFr17gH(*fu2+ |
# EXF)83gtE*fcIsZYlaDu |
# qGA7Pb=Q@w#6F!2mJ8=j |
# V6mPClwZ1qZ(X8hxHI@t |
# +N1wwS8h#0%jbB1e@z*x |
# #vvJMscG*oXs#ex7ivnc |
# p(xFYVK)91kJjfXr2!sB |
# IW5kB8Q4uvFQm_J%4bbu |
# m6^9y=RWroBNfpNzyBXI |
# 47=&3Jc5zzAg)X8(OF%s |
# )C_I%!6zJ!*appXlz=VE |
# Lv@^3rRYQECP)RkxlUs |
i=»0″ |
while [[ $i -lt 40 ]]; |
do |
LC_CTYPE=C tr -dc A-Za-z0-9_\!\@\#\$\%\^\&\*\(\)-+= |
You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.
Источник
aweijnitz / urandom_music.sh
# I really enjoyed «Bash One Liner — Compose Music From Entropy in /dev/urandom» |
# From http://blog.robertelder.org/bash-one-liner-compose-music/ |
# |
# This is a collection of one liners that work on Mac OSX |
# You need sox |
brew install sox |
# Major scale |
cat /dev/urandom | hexdump -v -e ‘ /1 «%u\n» ‘ | awk ‘ < split("0,2,4,5,7,9,11,12",a,","); for (i = 0; i ' | xxd -r -p | sox -v 0.25 -traw -r16000 -b32 -e signed-integer - -tcoreaudio |
# Minor scale |
cat /dev/urandom | hexdump -v -e ‘ /1 «%u\n» ‘ | awk ‘ < split("0,2,3,5,7,8,10,12",a,","); for (i = 0; i ' | xxd -r -p | sox -v 0.25 -traw -r16000 -b32 -e signed-integer - -tcoreaudio |
# Pentatonic |
cat /dev/urandom | hexdump -v -e ‘ /1 «%u\n» ‘ | awk ‘ < split("0,3,5,6,7,10,12",a,","); for (i = 0; i ' | xxd -r -p | sox -v 0.25 -traw -r16000 -b32 -e signed-integer - -tcoreaudio |
# Ryukyu (Okinawa) Japanese music scale |
cat /dev/urandom | hexdump -v -e ‘ /1 «%u\n» ‘ | awk ‘ < split("4,5,7,11",a,","); for (i = 0; i ' | xxd -r -p | sox -v 0.25 -traw -r16000 -b32 -e signed-integer - -tcoreaudio |
You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.
Источник
os.urandom, CPython, Linux и грабли
Хочу поведать поучительную историю ошибки в реализации функции urandom из модуля os в CPython на UNIX-подобных ОС (Linux, Mac OS X, etc.).
Return a string of n random bytes suitable for cryptographic use.
This function returns random bytes from an OS-specific randomness source. The returned data should be unpredictable enough for cryptographic applications, though its exact quality depends on the OS implementation. On a Unix-like system this will query /dev/urandom, and on Windows it will use CryptGenRandom().
Другими словами, к примеру, под Linux, urandom читает и возвращает байты из системного устройства /dev/urandom. Напомню, что в этой ОС существуют два типичных устройства-источника энтропии: /dev/random и /dev/urandom. Как известно, первое устройство «медленное» и блокирующее, а второе «быстрое», и вопреки распространенному мнению, оба они криптостойкие источники (псевдо-)случайных чисел. Сразу скажу, КДПВ к статье отношения не имеет и речь пойдёт совсем не о криптографии, безопасности и об OpenSSL с Heartbleed-ом.
Казалось бы, как можно ошибиться в реализации столь простой рутины? Как это часто бывает, дооптимизировались…
Возвратимся в конец 2004, выходит Half-Life 2 CPython 2.4, добавляя такие привычные всем фичи как декораторы функций, множества (set), обратный порядок обхода (reversed) и list comprehensions, которые по ссылке названы generator expressions. Как люди без них могли вообще разрабатывать софт на Питоне?!
Выше уже писалось, что в том числе добавили os.urandom, имплементированную на самом Питоне. Давайте пофантазируем, как можно было бы написать urandom:
def urandom ( n ) :
with open ( ‘/dev/urandom’ , ‘rb’ ) as rnd:
return rnd. read ( n )
def urandom ( n ) :
if rnd is None :
rnd = open ( ‘/dev/urandom’ , ‘rb’ )
return rnd. read ( n )
Какие проблемы появляются с такой реализацией? Скрипты, которые становятся демонами, падают при первом же вызове urandom после смерти родителя.
The child inherits copies of the parent’s set of open file descriptors. Each file descriptor in the child refers to the same open file description (see open(2)) as the corresponding file descriptor in the parent. This means that the two descriptors share open file status flags, current file offset, and signal-driven I/O attributes
Иначе говоря, файловые дескрипторы, принадлежащие питоновским file object-ам, после форка взаимосвязаны и ссылаются на один и тот же файл. Однако, если в одном процессе файл будет закрыт, то он не будет автоматически закрыт и в другом.
Ну fork и fork, скажете вы. Питон-то здесь причём? А при том что
- поверх него работает multiprocessing*
- через него происходит демонизация
* с исправлением #8713уже не всегда
Благодаря fork-анию в multiprocessing-е дети изначально находятся в состоянии, которое было у главного процесса перед размножением. Что касается процесса демонизации (превращением в сервис в терминах Windows) — см. PEP 3143. Где-то в самом разгаре там происходит вызов fork(). И если по лучшим традициям закрывать в новоиспечённом демоне все файловые дескрипторы напрямую, не через close() (например, так: os . closerange ( 3 , 256 ) ), то os.urandom() рушится.
Примерно этими словами объясняли пользователи CPython в начале 2005-го его разработчикам ошибку. Впрочем, Гвидо сначала пытался строить из себя дурака отнекиваться:
I recommend to close this as invalid. The daemonization code is clearly broken.
К счастью, люди смогли убедить царя в обратном, и, наконец, в июле кеширование /dev/urandom убрали — прошло более полугода. Обращаю внимание на то, как это сделали: в коде нет ни ссылки на номер бага, ни указания на причины патча, ни, в конце концов, просто поясняющего комментария. Работает, и хорошо.
No new syntax features were added in Python 3.4.
Ладно-ладно, если серьёзно, прогресс большой: кучу библиотек приняли, к примеру, asyncio, о котором уже много писали на Хабре, безопасность улучшили, освобождение объектов подкрутили — не мне об этом рассказывать. Главное, что перед релизом нашлись люди, которые посчитали, что реализация /dev/urandom на Питоне адски медленная, и true performance может обеспечить только старый добрый C. В общем функцию переписали… и снова наступили на те же самые грабли. И никакой PEP 446 им не помог. Патч вышел 24 апреля и на этот раз уже содержал в изобилии комментарии, ссылку на баг и даже regression тесты.
Какое мне до этого дело
import platform
platform . python_build ( )
( ‘default’ , ‘Apr 11 2014 13:05:11’ )
import os
print ( os . listdir ( ‘/proc/self/fd’ ) )
import random
print ( os . listdir ( ‘/proc/self/fd’ ) )
from os import urandom as _urandom
class Random ( _random. Random ) :
# .
def __init__ ( self , x = None ) :
# .
self . seed ( x )
self . gauss_next = None
def seed ( self , a = None , version = 2 ) :
# .
if a is None :
try :
a = int . from_bytes ( _urandom ( 32 ) , ‘big’ )
except NotImplementedError :
# .
Остается заметить, что import random делают Tornado, Twisted, uuid, и целая куча других библиотек, стандартных и не очень.
Надо заметить, что сначала я не совсем верно понял суть проблемы, необоснованно решив, что файловые дескрипторы ребёнка и родителя закрываются одновременно. Спасибо kekekeks за восстановление полной картины этого бага.
Источник
Are we using /dev/urandom on Mac OS and is that a bad idea? #594
Comments
NodeGuy commented Sep 10, 2017
The manual states:
I assume that applies to Mac OS. On Mac OS, /dev/urandom (which is the same as /dev/random ) has several problems:
- Beware of /dev/random on Mac OS X
- Yarrow requires entropy estimation, which is a very big challenge for implementation. It is hard to be sure how much entropy to collect before using it to reseed the PRNG. This problem is solved by Fortuna (PRNG), an improvement of Yarrow. Fortuna has 32 pools to collect entropy and removed the entropy estimator completely.[1]
- Yarrow-160 uses SHA1, which has widely been considered deprecated due to its first public collision.[1]
Like any other cryptographic primitive, a Yarrow generator has a
limited strength which we express in the size of the key. Yarrow-160
relies on the strength of three-key triple-DES and SHA-1. Systems that
have switched to the new cryptographic mechanisms (such as the new AES
cipher, when it is selected) in the interests of getting higher security
should also use a different version of Yarrow to rely on those new
mechanisms. If a longer key is necessary, then a future «larger» version
of Yarrow should be used; it makes no sense to use a 160-bit PRNG to
generate a 256-bit key for a block cipher, if 256 bits of security are
actually required.
From Mac OS’s man page for /dev/urandom:
Yarrow is a fairly resilient algorithm, and is believed to be resistant to non-root. The
quality of its output is however dependent on regular addition of appropriate entropy. If
the SecurityServer system daemon fails for any reason, output quality will suffer over
time without any explicit indication from the random device itself.
Paranoid programmers can counteract this risk somewhat by collecting entropy of their
choice (e.g. from keystroke or mouse timings) and seeding it into random directly before
obtaining important random numbers.
Should Sodium supply its own CSPRNG (such as Fortuna, the improvement over Yarrow that FreeBSD switched to but Mac OS did not) instead of reading from /dev/urandom when on Mac OS?
The text was updated successfully, but these errors were encountered:
Источник