Схема аутентификации на основе Iron строится вокруг идеи защищённой упаковки данных с возможностью последующего безопасного извлечения. В отличие от классического шифрования, Iron ориентирован на сериализацию, подпись и шифрование структуры данных в единый защищённый токен, который может быть использован как носитель состояния сессии.
В основе работы Iron лежит процесс «sealing» — запечатывания объекта. Входные данные проходят несколько этапов обработки:
Обратная операция — «unseal» — выполняет строго обратную последовательность проверок и преобразований. Любое несоответствие в подписи или структуре данных приводит к отказу в расшифровке.
Ключевая особенность заключается в том, что Iron объединяет аутентификацию и целостность данных в одном токене, минимизируя необходимость хранения состояния на сервере.
Результирующая строка после seal содержит несколько
логических слоёв:
Такая структура позволяет системе корректно обрабатывать устаревшие токены и обеспечивать совместимость между версиями библиотек.
Пример логики формирования:
sealed = encode(
version +
encryptionParams +
encryptedPayload +
integrityHash
)
Каждый элемент играет роль в проверке целостности и предотвращении подмены данных.
Iron часто применяется для реализации cookie-based сессий без серверного хранения состояния. В этом случае весь контекст пользователя помещается в зашифрованный токен.
Пример структуры сессии:
const session = {
userId: 42,
role: 'admin',
createdAt: Date.now()
};
После запечатывания:
const Iron = require('@hapi/iron');
const password = 'strong-32+character-secret-key';
const sealed = await Iron.seal(session, password, Iron.defaults);
На клиенте или при последующем запросе выполняется восстановление:
const unsealed = await Iron.unseal(sealed, password, Iron.defaults);
Любая попытка изменения строки sealed приводит к
невозможности восстановления объекта.
Iron использует набор параметров, влияющих на стойкость схемы:
encryption — алгоритм симметричного шифрованияintegrity — алгоритм контроля целостности (HMAC)saltBits — размер солиiterations — количество итераций KDFПример конфигурации:
const options = {
encryption: {
saltBits: 256,
algorithm: 'aes-256-cbc',
iterations: 100000
},
integrity: {
saltBits: 256,
algorithm: 'sha256',
iterations: 100000
},
ttl: 24 * 60 * 60 * 1000
};
Каждый параметр влияет на баланс между производительностью и стойкостью к атакующим моделям.
Iron сам по себе не выполняет идентификацию пользователя. Он обеспечивает транспортировку уже проверенных данных. Типичный поток выглядит следующим образом:
Таким образом, схема разделяет:
На практике Iron часто интегрируется в cookie-механизм:
reply.state('session', sealed, {
isSecure: true,
httpOnly: true,
path: '/',
sameSite: 'Strict'
});
При последующих запросах:
const session = await Iron.unseal(request.state.session, password, Iron.defaults);
Это позволяет серверу работать в stateless-режиме.
Одной из ключевых функций является защита от подмены payload. Даже минимальное изменение символа приводит к сбою MAC-проверки.
Пример сценария:
role: userrole: adminЭто достигается за счёт криптографической подписи, встроенной в структуру токена.
Iron поддерживает механизм ограничения времени жизни токена:
const options = {
ttl: 3600000 // 1 час
};
При истечении срока выполняется проверка временного окна, и токен считается недействительным даже при корректной подписи.
Это предотвращает повторное использование украденных токенов.
При использовании схемы часто возникают следующие проблемы:
Неправильное хранение секретного ключа
Несоответствие параметров
Отсутствие контроля TTL
Для повышения безопасности применяется ротация секретов:
const passwords = [
'old-secret-key',
'current-secret-key'
];
При расшифровке система пытается использовать несколько ключей, обеспечивая совместимость с ранее созданными токенами.
Новая сессия всегда создаётся с актуальным ключом.
Если токен повреждён или подделан, библиотека возвращает ошибку уровня безопасности:
В таких случаях требуется принудительная повторная аутентификация пользователя.
Схема на основе Iron особенно эффективна в системах:
Она снижает нагрузку на хранилища состояния и упрощает масштабирование, так как вся информация переносится в клиентский токен.
При этом критически важно сохранять строгий контроль над секретами и параметрами криптографии, поскольку компрометация ключа фактически означает компрометацию всех активных сессий.