2025, Dec 26 21:02

Истинная случайность в Python и роль CPU: когда использовать secrets

Разбираем, может ли Python обратиться к «истинной» случайности CPU, и почему для безопасных токенов и ключей следует использовать модуль secrets вместо random.

Может ли Python обратиться к «истинному» источнику случайности процессора или ему навсегда суждено довольствоваться ГПСЧ? Вкратце: Python предоставляет наиболее сильную случайность, доступную в вашей операционной системе, через модуль secrets. Считать ли это в итоге «настоящей случайностью», зависит от определений и от того, что именно ваша ОС подмешивает из аппаратных источников. Давайте посмотрим, как это выглядит на практике и как писать код, который делает всё правильно.

Контекст: TRNG против PRNG на современных CPU и в Python

Часто начинают с чисто программного генератора и быстро натыкаются на его пределы. Истинный генератор случайных чисел (TRNG) в чисто программной системе нередко описывают как невозможный. При этом современные процессоры добавляют аппаратные функции. Процессоры Intel начиная с Ivy Bridge (3‑е поколение) поддерживают RDRND, о котором заявлено, что он использует тепловой шум схем процессора для генерации случайных чисел. Современные CPU AMD также поддерживают RDRND начиная с AMD FX «Bulldozer» (2011), с поддержкой TRNG, схожей с функцией Intel. Отсюда практический вопрос: может ли программа на Python получить доступ к такой аппаратно поддержанной случайности напрямую, без внешних служб?

Пример проблемы: использование ГПСЧ в Python

Повсеместный модуль random — это генератор псевдослучайных чисел. Вот минимальный фрагмент, с которого начинают многие проекты:

import random as rnd
values_batch = [rnd.randint(0, 100) for _ in range(10)]
print("10 Random Numbers:")
print(values_batch)

Числа получаются, но их выдаёт ПСЧ. Вопрос в том, как перейти на источник, подходящий для задач безопасности и криптографии.

Что гарантирует модуль secrets

В Python 3.6 появился модуль secrets. Его задача — простым и переносимым способом предоставить доступ к лучшей случайности, которой располагает операционная система. В официальном описании сказано:

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

Иными словами, Python делегирует работу ОС, а ОС агрегирует свои наиболее сильные источники энтропии. Согласно обсуждению, большинство операционных систем в своём криптографически стойком генераторе используют помимо прочего и процессорные источники случайности, и именно они в итоге будут использоваться модулем secrets в Python. Есть и мнения, сомневающиеся, применяют ли конкретные ОС напрямую такие функции CPU, как RDRND; другие утверждают, что Linux, Windows и macOS задействуют процессорные рандомайзеры при их наличии. Дать строгое определение «истинного генератора случайных чисел» непросто, и этот разброс оценок лишь подчёркивает, что ярлык порой более философский, чем практический для прикладного кода.

Решение: используйте случайность ОС через secrets

Для разработчиков на Python практическая рекомендация проста: когда нужны случайные значения криптографического качества, используйте secrets. Он даёт наиболее сильную случайность, доступную на вашей платформе, не привязывая код к конкретной инструкции процессора или настройке ядра.

import secrets as sec
secure_batch = [sec.randbelow(101) for _ in range(10)]
print("10 OS-backed random numbers:")
print(secure_batch)

Это достигает исходной цели — десять целых от 0 до 100 — но опирается на самый защищённый источник случайности в ОС. То, складывает ли ОС внутрь такие возможности CPU, как RDRND, может различаться, и мнения расходятся; неизменно одно: secrets рассчитан на сценарии, где требуется безопасная случайность, в отличие от подходов, ориентированных на ПСЧ.

Почему это важно

Для токенов аутентификации, криптографических ключей и любых процессов, где опасна предсказуемость, разница между ПСЧ и защищённым источником на стороне ОС критична. Используя secrets, код на Python избегает ловушек детерминированных генераторов и не зависит жёстко от конкретных аппаратных функций. Модуль скрывает детали сбора энтропии ОС, стремясь к самому сильному источнику, доступному на этой системе.

Итоги

Если вам нужны непредсказуемые значения в Python, выбирайте secrets вместо random. Он перекладывает сложную часть на операционную систему и во многих средах включает процессорную случайность наряду с другими источниками. Считать ли это «истинной случайностью», — предмет спора и вопрос определений TRNG, но в практической разработке и инженерии безопасности модуль secrets — подходящий инструмент.