Документация Python неофициальный перевод
Содержание страницы

secrets – Генерация защищённых случайных чисел для управления секретамиsecrets – Generate secure random numbers for managing secrets

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

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


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

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

См. также

PEP 506

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

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

class secrets.SystemRandom

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

secrets.choice(seq)

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

secrets.randbelow(exclusive_upper_bound)

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

secrets.randbits(k)

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

Генерация токеновGenerating tokens

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

secrets.token_bytes(nbytes=None)

Возвращает случайную строку байтов, содержащую nbytes байтов.

Если nbytes не указан или равен None, используется DEFAULT_ENTROPY.

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

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

Если nbytes не указан или равен None, используется DEFAULT_ENTROPY.

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

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

Если nbytes не указан или равен None, используется DEFAULT_ENTROPY.

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

Сколько байтов должны использовать токены?How many bytes should tokens use?

Чтобы обеспечить защиту от атак методом перебора, токены должны обладать достаточной случайностью. К сожалению, то, что считается достаточным, со временем неизбежно возрастает, поскольку компьютеры становятся мощнее и способны перебирать больше вариантов за меньшее время. По состоянию на 2015 год считается, что 32 байта (256 бит) случайности достаточно для типичного варианта использования модуля secrets.

Для тех, кто хочет управлять длиной токенов самостоятельно, можно явно указать количество случайности, используемой для токенов, передав аргумент int различным функциям token_*. Этот аргумент интерпретируется как количество байтов случайности.

В противном случае, если аргумент не указан или равен None, функции token_* используют DEFAULT_ENTROPY.

secrets.DEFAULT_ENTROPY

Количество байтов случайности, используемое функциями token_* по умолчанию.

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

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

secrets.compare_digest(a, b)

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

Рецепты и рекомендацииRecipes and best practices

В этом разделе приведены рецепты и рекомендации по использованию 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://example.com/reset=' + secrets.token_urlsafe()