Как я могу создать случайное число, которое криптографически безопасно в python?


Я делаю проект на Python, и я хотел бы создать случайное число, которое является криптографически защищенным, как я могу это сделать? Я читал в интернете, что числа, генерируемые обычным рандомизатором, не являются криптографически безопасными, и что функция os.urandom(n) возвращает мне строку, а не число.

5 52

5 ответов:

вы можете получить список случайных чисел, просто применив ord функция над байтами, возвращенными os.urandom, такой

>>> import os
>>> os.urandom(10)
'm\xd4\x94\x00x7\xbe\x04\xa2R'
>>> type(os.urandom(10))
<type 'str'>
>>> map(ord, os.urandom(10))
[65, 120, 218, 135, 66, 134, 141, 140, 178, 25]

цитирую os.urandom документация

возвращает строку n случайный байт подходит для шифрования использовать.

эта функция возвращает случайные байты из источника случайности, специфичного для ОС. Возвращаемые данные должны быть достаточно непредсказуемыми для криптографические приложения, хотя их точное качество зависит от реализации ОС. В UNIX-подобной системе это будет запрос /dev/urandom, и на Windows он будет использовать CryptGenRandom().

так как вы хотите генерировать целые числа в некотором определенном диапазоне, это намного проще использовать random.SystemRandom класс вместо этого. Создание экземпляра этого класса дает вам объект, который поддерживает все методы random модуль, но с помощью os.urandom() - под одеяла. Примеры:

>>> from random import SystemRandom
>>> cryptogen = SystemRandom()
>>> [cryptogen.randrange(3) for i in range(20)] # random ints in range(3)
[2, 2, 2, 2, 1, 2, 1, 2, 1, 0, 0, 1, 1, 0, 0, 2, 0, 0, 0, 0]
>>> [cryptogen.random() for i in range(3)]  # random floats in [0., 1.)
[0.2710009745425236, 0.016722063038868695, 0.8207742461236148]

Etc. Используя urandom() непосредственно, вы должны изобрести свои собственные алгоритмы для преобразования случайных байтов он производит к результатам, которые вы хотите. Не делай этого ;-) SystemRandom это для вы.

обратите внимание на эту часть документов:

класса Random.SystemRandom ([seed])

класс, который использует ОС.функция urandom () для генерации случайных чисел из источников, предоставляемых операционной системой. Доступно не во всех системах. Не зависит от состояния программного обеспечения и последовательности не воспроизводимы. Соответственно, методы seed() и jumpahead () не имеют эффекта и игнорируются. Методы getstate() и setstate() вызывают NotImplementedError, если называемый.

Python 3.6 вводит новый секреты, который " обеспечивает доступ к наиболее защищенному источнику случайности, который обеспечивает ваша операционная система."Чтобы сгенерировать некоторые криптографически защищенные номера, вы можете позвонить secrets.randbelow().

secrets.randbelow(n)

который вернет число между 0 и n.

если вы хотите n - битное случайное число, под Python 2.4+, самый простой метод, который я нашел, это

import random
random.SystemRandom().getrandbits(n)

отметим, что SystemRandom использует os.urandom(), Так что результат этого метода только так хорошо, как ваша система urandom() реализация.

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

int(binascii.hexlify(os.urandom(n)),16)

здесь n является целым числом и, тем больше n is, чем больше сгенерированное целое число.

вам придется импортировать os и binascii первый.

результат этого кода может варьироваться в зависимости от платформы.