secrets — Генерация безопасных случайных чисел для управления secrets

Добавлено в версии 3.6.

Исходный код: Lib/secrets.py


Модуль secrets - используемый для создания шифровальным образом сильных случайных чисел, подходящих для руководящих данных, таких как пароли, идентификация счета, символы безопасности и связанные тайны.

В частности, secrets следует использовать вместо генератора псевдослучайных чисел по умолчанию в модуле random, который предназначен для моделирования и симуляции, а не безопасности или криптографии.

См.также

PEP 506

Случайные числа

Модуль secrets обеспечивает доступ к наиболее безопасному источнику случайности, предоставляемому операционной системой.

class secrets.SystemRandom

Класс для генерации случайных чисел с использованием высококачественных источников, предоставляемых операционной системой. Дополнительные сведения см. в разделе random.SystemRandom.

secrets.choice(sequence)

Возвращает случайно выбранный элемент из непустой последовательности.

secrets.randbelow(n)

Возвращает случайный int в диапазоне [0, n).

secrets.randbits(k)

Возвращает int с k случайными битами.

Создание маркеров

Модуль secrets предоставляет функции для генерации безопасных маркеров, подходящих для таких приложений, как сброс пароля, трудно угадываемые URL и т.п.

secrets.token_bytes([nbytes=None])

Возвращает случайный байт строка, содержащий nbytes число байтов. Если nbytes - None или не поставляемый, разумный дефолт - использовать.

>>> token_bytes(16)  
b'\xebr\x17D*t\xae\xd4\xe3S\xb6\xe2\xebP1\x8b'
secrets.token_hex([nbytes=None])

Возвращает случайный текст строка в шестнадцатеричной форме. строка имеет nbytes случайных байтов, каждый байт преобразуется в две шестнадцатеричные цифры. Если nbytes - None или не поставляемый, разумный дефолт - использовать.

>>> token_hex(16)  
'f9bf78b9a18ce6d46a0cd2b0b86df9da'
secrets.token_urlsafe([nbytes=None])

Возвращает случайную URL-безопасную текстововую строку, содержащая nbytes случайных байт. Текст равен Base64 кодированный, поэтому в среднем каждый байт содержит приблизительно 1.3 символа. Если nbytes - None или не поставляемый, разумные умолчания - использовать.

>>> token_urlsafe(16)  
'Drmhze6EPcv0fN_81Bj-nA'

Сколько байтов следует использовать токенам?

Чтобы быть защищенными от атаки грубой силы, маркеры должны иметь достаточную случайность. К сожалению, то, что считается достаточным, обязательно возрастет по мере того, как компьютеры станут более мощными и смогут делать больше догадок за более короткий период. По состоянию на 2015 год считается, что 32 байта (256 бит) случайности достаточно для типичного случая использования, ожидаемого для модуля secrets. Для тех, кто хочет управлять собственной длиной токена, можно явно указать, сколько случайности используемый для токенов, предоставив аргумент int различным функциям token_*. Этот аргумент принимается за число байт случайности для использования. В противном случае, если аргумент не указан, или если аргумент None, функции token_* будут использовать разумное значение по умолчанию.

Примечание

Это значение по умолчанию может быть изменено в любое время, в том числе во время обновлений.

Другие функции

secrets.compare_digest(a, b)

Возвращает True если строки a и b равны, иначе False, таким образом, чтобы снизить риск временные атаки. Дополнительные сведения см. в разделе hmac.compare_digest().

Рецепты и лучшие практики

В этом разделе приведены рецепты и рекомендации по использованию secrets для управления базовым уровнем безопасности.

Создайть восьмибуквенный буквенно-цифровой пароль:

import string
import secrets
alphabet = string.ascii_letters + string.digits
password = ''.join(secrets.choice(alphabet) for i in range(8))

Примечание

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

Произведите десять-символ алфавитно-цифровой пароль по крайней мере с одним строчным символ, по крайней мере одним заглавным символ и по крайней мере тремя цифры:

import string
import secrets
alphabet = string.ascii_letters + string.digits
while True:
    password = ''.join(secrets.choice(alphabet) for i in range(10))
    if (any(c.islower() for c in password)
            and any(c.isupper() for c in password)
            and sum(c.isdigit() for c in password) >= 3):
        break

Создание парольной фразы в стиле XKCD:

import secrets
# В стандартных системах Linux используйте удобный файл словаря. Другим платформам
# может потребоваться предоставить собственный список слов.
with open('/usr/share/dict/words') as f:
    words = [word.strip() for word in f]
    password = ' '.join(secrets.choice(words) for i in range(4))

Создать временный URL-адрес, содержащий маркер безопасности, подходящий для приложений восстановления пароля:

import secrets
url = 'https://mydomain.com/reset=' + secrets.token_urlsafe()