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'

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

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

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

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

Примечание

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

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

secrets.compare_digest(a, b)

Возвращает True, если строки или bytes-like objects a и b равны, в противном случае False, используя «сравнение с постоянным временем», чтобы уменьшить риск timing attacks. Дополнительные сведения см. в разделе hmac.compare_digest().

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

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

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

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

Примечание

Приложения не должны содержать store passwords in a recoverable format, будь то обычный текст или зашифрованные. Они должны быть обработаны и хэшированы с использованием криптографически надежной односторонней (необратимой) хэш-функции.

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

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-style passphrase:

import secrets
# On standard Linux systems, use a convenient dictionary file.
# Other platforms may need to provide their own word-list.
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()
Вернуться на верх