secrets.md
1> **Источник:** https://python-all.ru/3.16/library/secrets.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# `secrets` – Генерация защищённых случайных чисел для управления секретами89Добавлено в версии 3.6.1011**Исходный код:** [Lib/secrets.py](https://python-all.ru/src/main/Lib/secrets.py)1213---1415Модуль `secrets` используется для генерации криптостойких случайных чисел, подходящих для управления такими данными, как пароли, аутентификация учётных записей, токены безопасности и связанные с ними секреты.1617В частности, `secrets` следует использовать вместо стандартного генератора псевдослучайных чисел из модуля [`random`](https://python-all.ru/3.16/library/random.html#module-random), который предназначен для моделирования и симуляции, а не для безопасности или криптографии.1819> **См. также**20>21> [**PEP 506**](https://python-all.ru/3.16/library/secrets.html)2223## Случайные числа2425Модуль `secrets` предоставляет доступ к самому безопасному источнику случайных данных, который есть в операционной системе.2627#### `class secrets.SystemRandom`2829Класс для генерации случайных чисел с использованием источников наивысшего качества, предоставляемых операционной системой. См. [`random.SystemRandom`](https://python-all.ru/3.16/library/random.html#random.SystemRandom) для получения дополнительных сведений.3031#### `secrets.choice(seq)`3233Возвращает случайно выбранный элемент из непустой последовательности.3435#### `secrets.randbelow(exclusive_upper_bound)`3637Возвращает случайное целое число в диапазоне \[0, *exclusive\_upper\_bound*).3839#### `secrets.randbits(k)`4041Возвращает неотрицательное целое число с *k* случайными битами.4243## Генерация токенов4445Модуль `secrets` предоставляет функции для генерации защищённых токенов, подходящих для таких задач, как сброс паролей, создание URL-адресов, которые сложно угадать, и аналогичных.4647#### `secrets.token_bytes(nbytes=None)`4849Возвращает случайную строку байтов, содержащую *nbytes* байтов.5051Если *nbytes* не указан или равен `None`, используется [`DEFAULT_ENTROPY`](https://python-all.ru/3.16/library/secrets.html#secrets.DEFAULT_ENTROPY).5253```pycon54>>> token_bytes(16)55b'\xebr\x17D*t\xae\xd4\xe3S\xb6\xe2\xebP1\x8b'56```5758#### `secrets.token_hex(nbytes=None)`5960Возвращает случайную текстовую строку в шестнадцатеричном представлении. Строка содержит *nbytes* случайных байтов, каждый байт преобразуется в две шестнадцатеричные цифры.6162Если *nbytes* не указан или равен `None`, используется [`DEFAULT_ENTROPY`](https://python-all.ru/3.16/library/secrets.html#secrets.DEFAULT_ENTROPY).6364```pycon65>>> token_hex(16)66'f9bf78b9a18ce6d46a0cd2b0b86df9da'67```6869#### `secrets.token_urlsafe(nbytes=None)`7071Возвращает случайную текстовую строку, безопасную для использования в URL, содержащую *nbytes* случайных байтов. Текст кодируется в Base64, поэтому в среднем каждый байт даёт примерно 1,3 символа.7273Если *nbytes* не указан или равен `None`, используется [`DEFAULT_ENTROPY`](https://python-all.ru/3.16/library/secrets.html#secrets.DEFAULT_ENTROPY).7475```pycon76>>> token_urlsafe(16)77'Drmhze6EPcv0fN_81Bj-nA'78```7980### Сколько байтов должны использовать токены?8182Чтобы обеспечить защиту от [атак методом перебора](https://python-all.ru/3.16/library/secrets.html), токены должны обладать достаточной случайностью. К сожалению, то, что считается достаточным, со временем неизбежно возрастает, поскольку компьютеры становятся мощнее и способны перебирать больше вариантов за меньшее время. По состоянию на 2015 год считается, что 32 байта (256 бит) случайности достаточно для типичного варианта использования модуля `secrets`.8384Для тех, кто хочет управлять длиной токенов самостоятельно, можно явно указать количество случайности, используемой для токенов, передав аргумент [`int`](https://python-all.ru/3.16/library/functions.html#int) различным функциям `token_*`. Этот аргумент интерпретируется как количество байтов случайности.8586В противном случае, если аргумент не указан или равен `None`, функции `token_*` используют [`DEFAULT_ENTROPY`](https://python-all.ru/3.16/library/secrets.html#secrets.DEFAULT_ENTROPY).8788#### `secrets.DEFAULT_ENTROPY`8990Количество байтов случайности, используемое функциями `token_*` по умолчанию.9192Точное значение может измениться в любое время, в том числе во время выпусков обслуживания.9394## Другие функции9596#### `secrets.compare_digest(a, b)`9798Возвращает `True`, если строки или [байтоподобные объекты](https://python-all.ru/3.16/glossary.html#term-bytes-like-object) *a* и *b* равны, иначе `False`, используя «сравнение за постоянное время», чтобы снизить риск [атак по времени](https://python-all.ru/3.16/library/secrets.html). Подробнее см. [`hmac.compare_digest()`](https://python-all.ru/3.16/library/hmac.html#hmac.compare_digest).99100## Рецепты и рекомендации101102В этом разделе приведены рецепты и рекомендации по использованию `secrets` для обеспечения базового уровня безопасности.103104Сгенерировать восьмисимвольный буквенно-цифровой пароль:105106```python107import string108import secrets109alphabet = string.ascii_letters + string.digits110password = ''.join(secrets.choice(alphabet) for i in range(8))111```112113> **Примечание**114>115> Приложения не должны [**хранить пароли в восстанавливаемом формате**](https://python-all.ru/3.16/library/secrets.html), будь то в открытом виде или в зашифрованном. Они должны быть засолены и хешированы с использованием криптостойкой однонаправленной (необратимой) хеш-функции.116117Сгенерировать десятисимвольный буквенно-цифровой пароль, содержащий хотя бы одну строчную букву, хотя бы одну заглавную букву и хотя бы три цифры:118119```python120import string121import secrets122alphabet = string.ascii_letters + string.digits123while True:124 password = ''.join(secrets.choice(alphabet) for i in range(10))125 if (any(c.islower() for c in password)126 and any(c.isupper() for c in password)127 and sum(c.isdigit() for c in password) >= 3):128 break129```130131Сгенерировать [кодовую фразу в стиле XKCD](https://python-all.ru/3.16/library/secrets.html):132133```python134import secrets135# В стандартных системах Linux используйте подходящий файл словаря.136# На других платформах может потребоваться предоставить собственный список слов.137with open('/usr/share/dict/words') as f:138 words = [word.strip() for word in f]139 password = ' '.join(secrets.choice(words) for i in range(4))140```141142Сгенерировать труднопредсказуемый временный URL, содержащий защитный токен, подходящий для приложений восстановления пароля:143144```python145import secrets146url = 'https://example.com/reset=' + secrets.token_urlsafe()147```148