Iron — это библиотека для безопасной сериализации,
шифрования и подписи данных в JavaScript. Она широко используется в
экосистеме Node.js, особенно в проектах, где требуется надёжная защита
сессий, токенов и любых структурированных данных, передаваемых между
клиентом и сервером.
Главная идея Iron заключается в превращении произвольного JavaScript-объекта в строку, которая одновременно:
Результат работы Iron — это компактная строка, содержащая несколько уровней защиты:
Формат выглядит как единая строка с внутренней структурой, где каждый слой добавляет дополнительную безопасность.
iron.sealiron.seal используется для упаковки (seal) объекта в
защищённую строку.
Сигнатура:
Iron.seal(object, options, callback)
или промис-версия:
await Iron.seal(object, options)
import Iron from '@hapi/iron';
const obj = {
userId: 42,
role: 'admin'
};
const password = 'super-secure-password';
const sealed = await Iron.seal(obj, {
password,
ttl: 60 * 60 * 1000 // 1 час
});
console.log(sealed);
Результат — строка, содержащая зашифрованный объект.
iron.unsealЧтобы восстановить исходный объект, используется
unseal:
const unsealed = await Iron.unseal(sealed, {
password,
ttl: 60 * 60 * 1000
});
console.log(unsealed);
Если пароль неверный или срок действия истёк — операция завершится ошибкой.
Ключевой параметр безопасности.
password: 'very-long-random-string'
Требования:
Определяет время жизни зашифрованного объекта.
ttl: 1000 * 60 * 5 // 5 минут
После истечения времени unseal выдаст ошибку.
Iron использует симметричное шифрование (AES-256-GCM). Это обеспечивает:
Каждый sealed-объект содержит HMAC-подпись, которая проверяет:
sealПроцесс упаковки проходит несколько этапов:
Объект преобразуется в JSON:
JSON.stringify(object)
Из password выводятся криптографические ключи:
Данные шифруются AES:
plaintext → ciphertext
Создаётся HMAC:
HMAC(ciphertext + metadata)
Все части кодируются в безопасный формат (base64url-like строка).
unsealПри расшифровке выполняется обратная проверка:
Если хотя бы один шаг не проходит — выбрасывается ошибка.
Типичные ошибки:
Bad HMAC valueВозникает при:
Expired sealTTL истёк:
ttl: 1000 * 60
Cannot unsealОбобщённая ошибка:
const session = await Iron.seal({
userId: 123,
scope: ['read', 'write']
}, { password });
Сервер может хранить только строку без базы данных.
В отличие от JWT:
reply.state('session', sealed, {
isSecure: true,
httpOnly: true
});
Iron оптимизирован для серверных сценариев:
Однако:
crypto.randomBytes(32).toString('hex')
Чем меньше TTL — тем безопаснее:
Iron не зависит от схемы данных, но:
Iron использует:
Важно учитывать:
Приводит к:
Iron защищает данные, но не отменяет здравый смысл архитектуры: