Перейти к содержимому
SafePass

Профиль OPAQUE SafePass, версия 1

SafePass использует реализацию RFC 9807 из opaque-ke 4.0.1. Профиль фиксирует набор алгоритмов и параметров:

  • OPRF: Ristretto255.
  • Обмен ключами: TripleDH на Ristretto255 с SHA-512.
  • Функция усиления пароля: Argon2id v1.3, 65 536 КиБ, 3 прохода и 4 линии.
  • Контекст OPAQUE: SafePass authenticated API login v1.
  • Идентификатор сервера: SafePass OPAQUE server v1.
  • Идентификатор аккаунта: от 1 до 128 символов ASCII из букв, цифр, @, ., _ и -.
  • Пароль: 1–4096 байт. При регистрации и входе клиент должен использовать одно и то же кодирование UTF-8. Профиль не нормализует ввод.

Функции C ABI в packages/crypto_core/include/safepass_crypto_core.h оборачивают сериализованные типы библиотеки. Клиент хранит сериализованное состояние регистрации или входа только на время обмена. Настройка сервера содержит долговременный закрытый материал OPRF и обмена ключами. Её создают один раз и хранят в менеджере секретов или защищённом файле. Файл пароля OPAQUE содержит верификатор аккаунта. Состояние входа — кратковременный материал аутентификации. Если оно сохраняется между запросами, его шифруют отдельно от данных PostgreSQL.

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

Маршруты регистрации и входа версионированы. При начале регистрации API назначает случайный UUIDv4. Клиент должен сохранить его, поскольку поиск по имени аккаунта и вход по электронной почте отсутствуют. Завершение регистрации сохраняет файл пароля OPAQUE. Начало входа создаёт серверное состояние на три минуты. Перед записью в PostgreSQL оно шифруется отдельным 256-битным серверным ключом в конверте SPCR с привязкой AES-GCM к случайному идентификатору сессии и аккаунту. Завершение входа атомарно погашает состояние и выдаёт 15-минутный JWT только после успешного доказательства OPAQUE. Для неизвестного аккаунта отказ выглядит так же, как обычная ошибка входа. Лимит аутентификации — 20 запросов в минуту на IP.

HTTPS API использует канонический Base64URL без заполнения для сериализованных значений opaque-ke. Ограничение после декодирования — 16 КиБ. Эти сообщения передаются по TLS на маршрутах /v1/auth/…. Тесты Rust и проверка нативного C ABI покрывают регистрацию, успешный вход, закрепление ключа сервера, отказы при неверном пароле и неизвестном аккаунте, сериализацию состояния и размер фиктивного ответа.

Flutter использует Dart FFI и HTTPS. До финального сообщения клиент отклоняет неожиданный ключ сервера и держит 15-минутный JWT только в памяти. Вместе с ним выдаётся случайный 256-битный токен обновления. PostgreSQL хранит его SHA-256, обновляет токен в одной транзакции и отзывает семейство устройства при повторе погашенного токена. Токен истекает через 30 дней, семейство — не позднее чем через 90 дней. Выход отзывает одно семейство. Для аккаунта есть аутентифицированный маршрут отзыва всех семейств. JWT с sid прекращают действовать сразу после отзыва сессии. Устаревшие JWT без sid принимаются до истечения срока. Идентификатор аккаунта, URL API, закреплённый ключ и токен обновления хранятся в SQLCipher. При блокировке токен очищается из памяти. HTTP-тесты .NET проверяют выдачу и обновление токена, а интеграция PostgreSQL проверяет хеш и отзыв при повторе.

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

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

Срок жизни секретов

  • Исключать из журналов пароли, сообщения и сериализованные состояния OPAQUE, файлы паролей, настройку сервера, данные восстановления и ключи сейфа.
  • Хранить состояние клиента в памяти только до конца обмена.
  • Хранить настройку сервера вне базы и управлять ею через менеджер секретов. Замена делает существующие файлы паролей OPAQUE недействительными.
  • Перед записью в PostgreSQL API шифрует состояние, привязывает данные аутентификации конверта к случайному идентификатору сессии и аккаунту, устанавливает срок в три минуты и погашает состояние одной операцией.
  • Выдавать токен синхронизации только после финальной проверки OPAQUE. Клиенты с закреплением ключа проверяют его до отправки доказательства.

Зависимость

opaque-ke 4.0.1 распространяется под Apache-2.0 OR MIT. Транзитивные криптографические зависимости перечислены в Cargo.lock. Их нужно включить в SBOM и проверку лицензий релиза.

Документация