DAT (Distributed Access Token)
1. Обзор
По мере роста числа одновременно подключённых пользователей растёт и количество сессий (Session), что создаёт чрезмерную нагрузку на сессионный сервер.
DAT — это спецификация токена, созданная для того, чтобы решить проблему нагрузки на сессионный сервер и реализовать эффективную аутентификацию без совместного состояния между серверами (Stateless).
DAT — это строка из 5 фиксированных полей, разделённых точкой (.). Каждое поле можно вырезать по позиции разделителя без разбора JSON, а время истечения и область шифрования включены в саму спецификацию.
2. Проводной формат
expire . cid . plain . secure . signature| Поле | Тип | Кодирование | Примечание |
|---|---|---|---|
Время истечения | uint64 | десятичная строка | Unixtime (секунды) |
CID | uint64 | шестнадцатеричная строка | ID сертификата |
Открытые данные | Binary | Base64Url (без заполнения) | открытые данные |
Зашифрованные данные | Binary | Base64Url (без заполнения) | зашифрованные данные |
Подпись | Binary | Base64Url (без заполнения) | подпись |
2.1. Детальная спецификация полей
Время истечения : uint64 (Unix Time)
- Время истечения токена в виде 64-битного беззнакового целого числа в секундах (Seconds).
- Допускаются только чистые десятичные цифры. Знак, пробелы или разделители означают ошибку формата.
CID : Hex (uint64)
- Идентификатор сертификата (Certificate ID), используемого для проверки токена.
- Допускаются только чистые шестнадцатеричные цифры, префикс
0xне используется.
Открытые данные : Base64Url (Binary)
- Содержит данные, открытые для клиента. Поддерживаются не только строки, но и бинарные данные; клиент может декодировать и просмотреть их.
- Не шифруется. Помещать сюда конфиденциальные значения нельзя.
Зашифрованные данные : Base64Url (Binary)
- Содержит данные, скрытые от клиента. Они зашифрованы алгоритмом шифрования сертификата, поэтому клиент, не имеющий сертификата, не может расшифровать содержимое.
- Внутренняя структура —
IV(96bit) + шифротекст; IV генерируется заново при каждом шифровании.
Подпись : Base64Url (Binary)
- Данные подписи для проверки подделки и изменения токена. Создаются подписанием предшествующих полей алгоритмом подписи сертификата.
- Если проверка подписи не прошла, ни одному полю такого токена доверять нельзя.
3. Канонические правила (Canonical Rules)
Чтобы клиенты, реализованные на разных языках, интерпретировали один и тот же токен одинаково, приведённые ниже правила не должны расходиться между реализациями. Эталонная реализация — Rust (dat-rust), и все остальные реализации приведены в соответствие с ней.
3.1. Разбор числовых полей
expire и cid интерпретируются строго. Все приведённые ниже входные данные отклоняются как ошибка формата.
| Пример ввода | Результат | Причина |
|---|---|---|
100 | принято | чистое десятичное число |
007 | принято | ведущие нули допускаются |
+100 | отклонено | знак недопустим |
-1 | отклонено | знак недопустим |
" 100 " | отклонено | пробелы недопустимы |
1_0 | отклонено | разделители недопустимы |
0x10 | отклонено | префиксы недопустимы |
zzzz | отклонено | не число |
"" | отклонено | пустая строка |
18446744073709551616 | отклонено | выход за диапазон uint64 |
Почему требуется строгость
Снисходительный парсер превращает -1 в максимальное значение uint64 и создаёт фактически неистекающий токен либо молча заменяет нечисловое значение на 0. Если снисходительность различается между реализациями, один и тот же токен в одном месте пройдёт, а в другом будет отклонён — и совместимость нарушится.
3.2. Определение истечения
У токена DAT и у сертификата границы истечения разные. Не путайте их.
| Объект | Условие действительности | Ровно в момент истечения (expire == now) |
|---|---|---|
| Токен DAT | expire > now | отклоняется как истёкший |
| Сертификат | expire >= now | ещё действителен |
Токен становится недействительным ровно в момент истечения, а сертификат действителен до этого момента включительно. Сертификат должен жить на один тик дольше токена, чтобы можно было проверить токен, выданный на самой границе.
3.3. Пустая полезная нагрузка secure
Если шифровать нечего, secure — это пустая строка.
encrypt(пустой ввод)→ пустой вывод (не добавляются ни IV, ни тег GCM)decrypt(пустой ввод)→ пустой вывод- Если значение непустое, но не длиннее IV (12 байт), это ошибка расшифрования.
1893456000.1a.SGVsbG8..T3RoZXItc2lnbmF0dXJl
↑ корректный токен с пустым местом под secure4. Выдача и проверка
4.1. Процедура выдачи
- Из имеющихся у менеджера сертификатов выбирается доступный для выдачи (issuable).
- Вычисляется
expire = now + dat_ttl_seconds. plainкодируется в Base64Url, аsecureсначала шифруется, затем кодируется в Base64Url.- Строка
expire.cid.plain.secureподписывается, и подпись добавляется последним полем.
4.2. Процедура проверки
- Строка разбивается точкой (
.) на 5 полей. Иное количество полей — ошибка формата. - Проверяется
expire. Истёкший токен отклоняется до проверки подписи. - По
cidотыскивается сертификат. Если его нет, проверка невозможна. - Подпись проверяется по участку
expire.cid.plain.secure. - Только после успешной проверки выполняется расшифрование
secure.
Не доверяйте значениям до проверки подписи
Некоторые реализации предоставляют API, извлекающий поля без проверки подписи (семейство parse without verify). Эти значения полностью контролируются атакующим, поэтому использовать их следует только для логирования и отладки.
5. Сравнение с JWT
DAT и JWT (JSON Web Token) разделяют структуру токена, разбитого точками (.), и способ проверки через подпись, однако во внутреннем устройстве между ними есть следующие ключевые различия.
5.1. Сравнение структурных различий
Структура JWT
header body signature Base64Url (JSON String) Base64Url (JSON String) Base64Url (Binary) Структура DAT
Время истечения CID Открытые данные Зашифрованные данные Подпись Unixtime (uint64) Hex (uint64) Base64Url (Binary) Base64Url (Encrypt Binary) Base64Url (Binary)
5.2. Ключевые различия
- Облегчённость на основе Binary: JWT оперирует заголовком (Header) и телом (Body) в виде JSON-строк, тогда как DAT работает непосредственно с бинарными данными (Binary), оптимизируя размер данных и повышая эффективность разбора.
- Встроенная безопасность (поле
Зашифрованные данные): В JWT полезная нагрузка (Payload) по умолчанию передаётся в открытом виде, и при необходимости шифрования приходится применять отдельную спецификацию вроде JWE. DAT же поддерживает шифрование непосредственно в самом токене через полеЗашифрованные данные. - Принудительное ограничение срока действия: В JWT поле
exp(Claims) необязательно, тогда как в DAT полеВремя истечениязакреплено в структуре токена, поэтому проверка срока действия выполняется обязательно. - Отсутствие согласования алгоритма: JWT носит значение
algв собственном заголовке, из-за чего возникает поверхность атаки на путаницу алгоритмов. В DAT алгоритм определяет сертификат, и в токене сведений об алгоритме нет.