secrets — Generate secure random numbers for managing secrets

Нове в версії 3.6.

Вихідний код: Lib/secrets.py


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

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

Дивись також

PEP 506

Випадкові числа

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

class secrets.SystemRandom

Клас для генерації випадкових чисел з використанням джерел найвищої якості, наданих операційною системою. Дивіться random.SystemRandom для отримання додаткової інформації.

secrets.choice(sequence)

Return a randomly-chosen element from a non-empty sequence.

secrets.randbelow(n)

Return a random int in the range [0, n).

secrets.randbits(k)

Return an int with k random bits.

Генерація токенів

Модуль 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)

Return True if strings a and b are equal, otherwise False, in such a way as to reduce the risk of timing attacks. See hmac.compare_digest() for additional details.

Рецепти та найкращі практики

Цей розділ містить рецепти та найкращі методи використання secrets для керування базовим рівнем безпеки.

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

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

Примітка

Applications should not store passwords in a recoverable format, whether plain text or encrypted. They should be salted and hashed using a cryptographically-strong one-way (irreversible) hash function.

Згенеруйте буквено-цифровий пароль із десяти символів, який містить принаймні один символ у нижньому регістрі, принаймні один символ у верхньому регістрі та принаймні три цифри:

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
# 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()