paseto_dart

Dart неофициальная реализация PASETO (Platform-Agnostic Security Tokens) — современная криптографически защищенная альтернатива JWT.

Warning

Библиотека находится в стадии разработки и может содержать ошибки. Используйте на свой страх и риск.

Что такое PASETO

PASETO — это протокол для создания безопасных токенов доступа, разработанный в 2018 году как альтернатива JWT/JOSE, устраняющий его основные недостатки безопасности:

  • Фиксированный набор алгоритмов в каждой версии — устраняет уязвимости, связанные с выбором алгоритма
  • Строгое разделение режимов на local (шифрование) и public (подпись) — предотвращает путаницу
  • Строгая спецификация формата — минимизирует ошибки реализации
  • Современная криптография — использует XChaCha20 и BLAKE2b

🚀 Установка

dependencies:
  paseto_dart: ^1.0.0

📋 Поддерживаемые версии PASETO

Note

Данная библиотека поддерживает только PASETO v4, который является рекомендуемым для новых проектов.

Версия Поддержка Описание
v1 Legacy (RSA + AES-CTR) - не поддерживается
v2 General purpose (NaCl/libsodium) - не поддерживается
v3 NIST-compliant - не поддерживается
v4 Modern (рекомендуется)
PASERK PASETO формат представления ключей - не поддерживается

🔐 Быстрый старт

Примеры использования библиотеки можно найти в example.

📚 Руководство по выбору типа токена

Тип токена Когда использовать Преимущества
local - Защита чувствительных данных
- Хранение секретов
- Данные зашифрованы
- Доступны только с ключом
public - Авторизация
- Аутентификация
- Проверка без секретного ключа
- Совместим с подходом JWT

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

  1. Включайте срок действия (exp) в токены авторизации
  2. Всегда проверяйте версию токена перед использованием
  3. Храните ключи в безопасности
  4. Для токенов авторизации используйте режим public
  5. Для защиты данных используйте режим local

⚠️ Правильная реализация авторизации

Важно! Токены PASETO не предназначены для повторного использования в качестве долгосрочных токенов доступа.

PASETO не имеет встроенной защиты от атак повторного воспроизведения (повторное использование токена). Если токен перехвачен, злоумышленник может использовать его до истечения срока действия.

Рекомендуемая архитектура авторизации

  1. Используйте двухуровневую систему токенов:
    • Краткосрочные токены доступа PASETO (5-15 минут)
    • Долгосрочные токены обновления (хранятся в базе данных сервера)
// Пример создания токенов в двухуровневой системе авторизации
Future<AuthTokens> createAuthTokens(User user) async {
  // Краткосрочный токен доступа
  final accessTokenData = {
    'sub': user.id,
    'exp': DateTime.now().add(Duration(minutes: 15)).millisecondsSinceEpoch ~/ 1000,
    'jti': generateUniqueId(), // ID токена для защиты от повторного использования
  };
  
  // Создаем пакет с данными
  final package = Package(
    content: utf8.encode(jsonEncode(accessTokenData)),
  );

  // Подписываем с помощью PublicV4
  final signedPayload = await PublicV4.sign(
    package,
    keyPair: authKeyPair,
  );
  
  // Создаем токен
  final token = Token(
    header: PublicV4.header,
    payload: signedPayload,
    footer: null,
  );
  
  // Генерируем токен обновления и сохраняем его в базе данных
  final refreshToken = generateSecureRandomString();
  await storeRefreshTokenInDatabase(user.id, refreshToken);
  
  return AuthTokens(
    accessToken: token.toTokenString,
    refreshToken: refreshToken,
  );
}
  1. Добавьте проверку состояния на сервере:

    • Храните ID использованных токенов
    • Поддерживайте белый/черный список активных сессий
    • Реализуйте механизм немедленного отзыва токена
  2. Для критических операций используйте одноразовые токены:

    • Добавьте уникальный идентификатор (jti) в полезную нагрузку
    • Проверяйте на сервере, был ли токен уже использован
    • После использования добавляйте ID токена в список использованных токенов

Чего не следует делать

Не используйте PASETO как постоянные токены доступа:

// НЕПРАВИЛЬНО: использование долгосрочного токена для всех запросов
final userData = {
  'sub': 'user123',
  'exp': DateTime.now().add(Duration(days: 30)).millisecondsSinceEpoch ~/ 1000
};

Не полагайтесь только на срок действия токена для обеспечения безопасности:

// НЕПРАВИЛЬНО: нет дополнительных проверок на стороне сервера
if (tokenData['exp'] > currentTimestamp) {
  // Предоставление доступа только на основе срока действия
  grantAccess();
}

⚙️ Реализации PASETO на других языках

PASETO имеет реализации на многих языках. Вы можете найти их на официальном сайте.

📖 Полезные ссылки