PyNaCl – библиотека криптографии

онлайн тренер по питону
Онлайн-тренажер Python 3 для начинающих

Теория без воды. Задачи с автоматической проверкой. Подсказки на русском языке. Работает в любом современном браузере.

начать бесплатно

Введение

В мире криптографии надёжность, простота и безопасность имеют первостепенное значение. Когда речь заходит о безопасной передаче данных, аутентификации и цифровых подписях, библиотека PyNaCl предлагает мощный, современный и проверенный инструментарий.

PyNaCl — это Python-обёртка над библиотекой libsodium, реализацией криптографической библиотеки NaCl (Networking and Cryptography Library). Она предоставляет доступ к современным алгоритмам, включая Curve25519, Ed25519, XSalsa20-Poly1305 и SHA-512.

PyNaCl популярен в проектах, где безопасность критична: обмен сообщениями, защищённые API, P2P-протоколы, ZeroMQ, VPN и блокчейн-проекты. В этой статье представлен полный обзор возможностей PyNaCl, с примерами и рекомендациями.

Основная часть

Установка

pip install pynacl

Архитектура PyNaCl

  • Box: шифрование/расшифровка между двумя ключами

  • SecretBox: симметричное шифрование

  • SigningKey/VerifyKey: цифровая подпись

  • PublicKey/PrivateKey: публично-ключевая криптография

  • Nonce: одноразовый уникальный идентификатор


Генерация ключей

from nacl.public import PrivateKey

private_key = PrivateKey.generate()
public_key = private_key.public_key

Box: шифрование между двумя пользователями

from nacl.public import Box

alice_box = Box(alice_private, bob_public)
ciphertext = alice_box.encrypt(b"Hello")

bob_box = Box(bob_private, alice_public)
plaintext = bob_box.decrypt(ciphertext)

Box использует Curve25519 для обмена ключами и XSalsa20 + Poly1305 для шифрования/аутентификации.


SecretBox: симметричное шифрование

from nacl.secret import SecretBox
from nacl.utils import random

key = random(SecretBox.KEY_SIZE)
box = SecretBox(key)
cipher = box.encrypt(b"Top Secret")
message = box.decrypt(cipher)

SigningKey и VerifyKey: цифровая подпись

from nacl.signing import SigningKey

signing_key = SigningKey.generate()
verify_key = signing_key.verify_key

signed = signing_key.sign(b"Important data")
verify_key.verify(signed)

PyNaCl использует Ed25519 — быстрый и надёжный алгоритм подписи.


Хэш-функции

from nacl.hash import sha512
from nacl.encoding import HexEncoder

hash = sha512(b"message", encoder=HexEncoder)

Работа с nonce (одноразовый идентификатор)

nonce = random(Box.NONCE_SIZE)

Nonce должен быть уникальным для каждой операции. Это гарантирует защиту от повторной атаки (replay attack).


Ключевые API и методы

Метод / Класс Назначение
PrivateKey.generate() Генерация приватного ключа
Box.encrypt() Шифрование сообщения
Box.decrypt() Расшифровка сообщения
SecretBox.encrypt() Симметричное шифрование
SigningKey.sign() Создание подписи
VerifyKey.verify() Проверка подписи

Использование в API / Web / P2P

  • API: подпись запроса клиента (вместо токена)

  • IoT: защищённый обмен сообщениями через Box

  • P2P-сети: Curve25519 для обмена ключами

  • Файловая безопасность: SecretBox для защиты на диске


Сравнение с другими библиотеками

Библиотека Ассиметрия Симметрия Подпись Преимущества
PyNaCl Да Да Да Современные стандарты
Cryptography Да Да Да Универсальность
PyCrypto Частично Частично Нет Устаревшая

Лучшие практики

  • Используйте случайные nonce, не повторяйте их

  • Не храните закрытые ключи в открытом виде

  • Проверяйте подписи перед декодированием

  • Используйте SecretBox для защищённых логов

Полный список функций и свойств библиотеки PyNaCl с описанием, сгруппированных по категориям


Шифрование с открытым ключом (Public-key Encryption)

Функция Описание
PrivateKey.generate() Генерация приватного ключа для алгоритма Curve25519.
PrivateKey.encode() Сериализует приватный ключ (байты).
PublicKey.encode() Сериализует публичный ключ.
PrivateKey(public_key) Загружает приватный ключ из байтов.
PublicKey(public_key) Загружает публичный ключ из байтов.
Box(private_key, public_key) Создаёт шифратор Box для пары ключей.
box.encrypt(message) Шифрует сообщение (автоматически генерируется nonce).
box.decrypt(ciphertext) Расшифровывает сообщение.

Симметричное шифрование (SecretBox)

Функция Описание
SecretBox(key) Создаёт объект симметричного шифрования (AES-GCM-подобное шифрование).
SecretBox.generate() Генерирует безопасный симметричный ключ.
box.encrypt(message) Шифрует сообщение (возвращает nonce + ciphertext).
box.decrypt(ciphertext) Расшифровывает сообщение (при наличии nonce).
SecretBox.KEY_SIZE Размер ключа (32 байта).
SecretBox.NONCE_SIZE Размер nonce (24 байта).

Цифровые подписи (Signing)

Функция Описание
SigningKey.generate() Генерирует приватный ключ для подписи (Ed25519).
SigningKey.sign(message) Подписывает сообщение (возвращает подпись + сообщение).
VerifyKey.verify(signed) Проверяет подпись и извлекает сообщение.
SigningKey.encode() Сериализует ключ в байты.
VerifyKey.encode() Сериализует публичный ключ.
SigningKey.verify_key Получает публичный ключ из приватного.
SigningKey(seed) Создаёт ключ из seed (32 байта).

Хеширование и безопасные сравнения

Функция Описание
nacl.hash.sha256(data) Возвращает SHA256-хеш от данных.
nacl.hash.sha512(data) Возвращает SHA512-хеш.
nacl.utils.random(size) Генерирует криптографически стойкие случайные байты.
nacl.utils.random_bytes(size) Альтернатива random.
nacl.utils.EncryptedMessage(...) Объект с зашифрованными данными.
nacl.bindings.sodium_memcmp(a, b) Безопасное (constant-time) сравнение байтов.

Работа с паролями (Password hashing)

Функция Описание
nacl.pwhash.str(password) Хеширует пароль с помощью Argon2id (для хранения).
nacl.pwhash.verify(stored_hash, password) Проверяет пароль по хешу.
nacl.pwhash.kdf(size, password, salt, opslimit, memlimit) Генерация ключа из пароля.
nacl.pwhash.scryptsalsa208sha256(...) Старый API для scrypt (поддерживается для совместимости).

Константы и размеры

Функция Описание
nacl.secret.SecretBox.KEY_SIZE Размер ключа: 32 байта.
nacl.public.Box.NONCE_SIZE Размер nonce: 24 байта.
nacl.signing.SIGNATURE_SIZE Размер Ed25519 подписи: 64 байта.
nacl.pwhash.SALTBYTES Длина соли: 16 байт.
nacl.pwhash.argon2id.OPSLIMIT_* Пресеты: INTERACTIVE, MODERATE, SENSITIVE.
nacl.encoding.RawEncoder Кодировщик для байтов (без base64).
nacl.encoding.Base64Encoder Кодирует и декодирует данные через Base64.

Заключение

PyNaCl предоставляет простую, но мощную криптографическую модель, основанную на безопасных алгоритмах. Он позволяет реализовать надёжную защиту данных, обмена сообщениями, авторизации и верификации. Особенно полезен для разработчиков API, криптовалют, мессенджеров и всех, кому требуется современная криптография в Python.