Secrets.token hex: примеры (PYTHON)

Применение функции token_hex для генерации защищенных токенов
Раздел: Криптография, Генерация токенов
secrets.token_hex(nbytes): str

Описание функции secrets.token_hex

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

Когда используется: Функция применяется, когда требуется создать безопасную случайную строку в шестнадцатеричном формате. Типичные случаи использования включают генерацию уникальных идентификаторов сессий, токенов сброса пароля, ключей API или случайных солевых значений для хеширования.

Аргументы:

  • nbytes (опциональный, тип int): Количество случайных байтов, которые будут сгенерированы перед преобразованием в шестнадцатеричную строку. Если аргумент равен None или не указан, используется значение по умолчанию, определяемое реализацией (в стандартной реализации CPython это 32 байта). Значение должно быть целым неотрицательным числом.

Возвращаемое значение: Функция возвращает строку (str) в нижнем регистре, состоящую из шестнадцатеричных цифр (символы 0-9, a-f). Длина возвращаемой строки в два раза превышает значение nbytes, так как каждый байт представляется двумя шестнадцатеричными символами.

Короткие примеры использования

Пример с использованием значения по умолчанию (nbytes=None).

import secrets
token = secrets.token_hex()
print(token)
print(len(token))
# Результат будет разным при каждом запуске, например:
# 1c4f2a8d9e3b7c5a6f0e1d2c3b4a59687f8e7d6c5b4a3f2e1d0c9b8a7f6e5d4
# 64

Пример с заданным количеством байт (nbytes=8).

import secrets
token = secrets.token_hex(8)
print(token)
print(len(token))
# Пример результата:
# a3f7c5e81b9d2a4f
# 16

Пример с нулевым количеством байт.

import secrets
token = secrets.token_hex(0)
print(repr(token))
print(len(token))
# Результат:
# ''
# 0

Похожие функции в Python

  • secrets.token_bytes(nbytes=None): Генерирует случайную последовательность байт. Возвращает объект bytes. Предпочтительнее использовать, когда нужны именно байты, а не их строковое представление.
  • secrets.token_urlsafe(nbytes=None): Генерирует случайную строку, безопасную для использования в URL. Кодирует байты в формат Base64, заменяя символы + и / на - и _. Возвращает строку (str). Используется для токенов, которые будут передаваться в веб-адресах.
  • os.urandom(nbytes): Низкоуровневая функция, возвращающая случайные байты из источника, предоставляемого ОС. Возвращает объект bytes. Модуль secrets использует эту функцию внутри себя. Прямое использование os.urandom оправдано при работе с бинарными данными без необходимости строкового представления.
  • random.getrandbits(k) (из модуля random): Генерирует целое число с k случайными битами. Важно: Этот модуль не предназначен для криптографических целей и не должен использоваться для генерации секретов.

Альтернативы в других языках программирования

PHP: Комбинация функций random_bytes() и bin2hex(). Функция random_bytes() генерирует криптографически безопасные псевдослучайные байты.

$length = 16;
$bytes = random_bytes($length);
$token = bin2hex($bytes);
echo $token; // Пример: 1a2b3c4d5e6f7890

JavaScript (Node.js): Используется модуль crypto и метод randomBytes().

const crypto = require('crypto');
const token = crypto.randomBytes(8).toString('hex');
console.log(token); // Пример: a3f7c5e81b9d2a4f

Java: Класс SecureRandom для генерации случайных байт, которые затем преобразуются в шестнадцатеричную строку.

import java.security.SecureRandom;
SecureRandom random = new SecureRandom();
byte[] bytes = new byte[8];
random.nextBytes(bytes);
StringBuilder sb = new StringBuilder();
for (byte b : bytes) {
    sb.append(String.format("%02x", b));
}
String token = sb.toString();
System.out.println(token); // Пример: a3f7c5e81b9d2a4f

Go: Пакет crypto/rand предоставляет функцию Read для заполнения среза байт.

package main
import (
    "crypto/rand"
    "encoding/hex"
    "fmt"
)
func main() {
    bytes := make([]byte, 8)
    rand.Read(bytes)
    token := hex.EncodeToString(bytes)
    fmt.Println(token) // Пример: a3f7c5e81b9d2a4f
}

C#: Используется класс System.Security.Cryptography.RandomNumberGenerator.

using System;
using System.Security.Cryptography;
byte[] bytes = new byte[8];
RandomNumberGenerator.Fill(bytes);
string token = Convert.ToHexString(bytes).ToLowerInvariant();
Console.WriteLine(token); // Пример: a3f7c5e81b9d2a4f

Типичные ошибки при использовании

Передача аргумента нецелого типа вызывает исключение TypeError.

import secrets
try:
    token = secrets.token_hex("8")
except TypeError as e:
    print(f"Ошибка: {e}")
Ошибка: 'str' object cannot be interpreted as an integer

Передача отрицательного числа вызывает исключение ValueError, так как количество байт не может быть отрицательным.

import secrets
try:
    token = secrets.token_hex(-1)
except ValueError as e:
    print(f"Ошибка: {e}")
Ошибка: negative argument not allowed

Ожидание конкретной длины строки без учета того, что длина результата в два раза больше nbytes. Это не ошибка выполнения, но логическая ошибка в коде.

import secrets
# Ожидается строка длиной 8 символов, но получится 16.
token = secrets.token_hex(8)  # Длина token = 16 символов.
if len(token) == 8:
    print("Длина верная")
else:
    print(f"Неожиданная длина: {len(token)}")
Неожиданная длина: 16

История изменений функции

Функция secrets.token_hex была добавлена в Python 3.6 вместе со всем модулем secrets. С момента добавления в стандартной библиотеке не претерпевала значительных изменений в своей сигнатуре или основном поведении.

Расширенные примеры использования

Создание токена для сброса пароля с фиксированной длиной и добавлением префикса для идентификации типа.

Пример python
import secrets
import time

def generate_reset_token(user_id: str) -> str:
    timestamp = hex(int(time.time()))[2:]
    random_part = secrets.token_hex(16)  # 32 шестнадцатеричных символа
    return f"reset_{user_id}_{timestamp}_{random_part}"

print(generate_reset_token("user123"))
# Пример: reset_user123_642b1c23_1c4f2a8d9e3b7c5a6f0e1d2c3b4a59687

Генерация нескольких уникальных ключей для пакетной обработки.

Пример python
import secrets
keys = {secrets.token_hex(4) for _ in range(5)}  # Используем множество для уникальности
print(keys)
# Пример: {'a3f7c5e8', '1b9d2a4f', 'c5e81b9d', '2a4fc5e8', 'e81b9d2a'}
print(f"Сгенерировано уникальных ключей: {len(keys)}")

Создание соли (salt) для хеширования пароля с помощью библиотеки hashlib.

Пример python
import secrets
import hashlib

def hash_password(password: str, salt: str = None) -> tuple:
    if salt is None:
        salt = secrets.token_hex(16)  # Генерируем соль длиной 32 символа
    # Используем PBKDF2 для хеширования
    key = hashlib.pbkdf2_hmac('sha256', password.encode(), salt.encode(), 100000)
    return salt, key.hex()

salt, hashed = hash_password("my_secure_password")
print(f"Соль: {salt}")
print(f"Хеш: {hashed[:32]}...")  # Выводим часть хеша

Использование в контексте веб-приложения Flask для установки секретного ключа сессии.

Пример python
# app.py (пример)
from flask import Flask, session
import secrets

app = Flask(__name__)
# Генерация постоянного секретного ключа для подписи cookie сессий.
# В реальном приложении это значение должно храниться в конфигурации,
# а не генерироваться при каждом запуске.
app.secret_key = secrets.token_hex(32)
print(f"Секретный ключ приложения: {app.secret_key[:16]}...")

@app.route('/login')
def login():
    session['user_token'] = secrets.token_hex(16)
    return f"Токен сессии установлен: {session['user_token']}"

Создание одноразового кода подтверждения фиксированной длины (например, 6 символов).

Пример python
import secrets
# Генерируем 3 байта, чтобы получить 6 шестнадцатеричных символов.
verification_code = secrets.token_hex(3)
print(f"Ваш код подтверждения: {verification_code.upper()}")  # В верхнем регистре
# Пример: Ваш код подтверждения: A3F7C5

питон secrets.token_hex function comments

En
Secrets.token hex Generate secure random hex string