Установка и первый запуск

Библиотека Iron распространяется через пакетный менеджер npm, что делает процесс установки стандартным для экосистемы JavaScript. Перед установкой требуется наличие установленной среды выполнения Node.js версии не ниже LTS-релиза.

Установка выполняется командой:

npm install @hapi/iron

Пакет устанавливается локально в директорию проекта и добавляется в зависимости package.json. При необходимости глобального использования (что встречается крайне редко), допускается установка с флагом -g, однако в типичных сценариях Iron используется как часть серверного приложения.

Структура после установки:

node_modules/
  @hapi/
    iron/
package.json
package-lock.json

Ключевой экспорт библиотеки доступен через модуль:

const Iron = require('@hapi/iron');

В средах с поддержкой ES-модулей используется синтаксис:

import Iron from '@hapi/iron';

Конфигурация окружения

Iron предназначен для безопасной сериализации и шифрования данных. Основной параметр — пароль (secret), используемый для генерации ключей шифрования.

Минимальные требования к паролю:

  • строка длиной не менее 32 символов
  • высокая энтропия (случайность)
  • хранение вне исходного кода (например, в переменных окружения)

Пример:

export IRON_SECRET="very-long-secure-password-1234567890"

Использование в коде:

const password = process.env.IRON_SECRET;

Базовые принципы работы

Iron реализует механизм “sealed objects” — запечатанных объектов. Это означает:

  • данные сериализуются
  • шифруются
  • подписываются для защиты от подделки

Процесс включает:

  1. Преобразование объекта в строку
  2. Генерацию ключей
  3. Шифрование (AES)
  4. Добавление HMAC-подписи

Результат — строка, безопасная для передачи или хранения.


Первый пример: запечатывание данных

const Iron = require('@hapi/iron');

async function run() {
    const password = 'super-secure-password-1234567890';
    
    const obj = {
        userId: 123,
        role: 'admin'
    };

    const sealed = await Iron.seal(obj, password, Iron.defaults);

    console.log(sealed);
}

run();

Результат — длинная строка, содержащая:

  • зашифрованные данные
  • параметры шифрования
  • подпись

Распаковка данных

Для восстановления объекта используется метод unseal:

const Iron = require('@hapi/iron');

async function run() {
    const password = 'super-secure-password-1234567890';

    const sealed = '...строка...';

    const unsealed = await Iron.unseal(sealed, password, Iron.defaults);

    console.log(unsealed);
}

run();

Если:

  • пароль неверен
  • данные были изменены
  • срок действия истёк

будет выброшено исключение.


Работа с параметрами безопасности

Iron предоставляет набор настроек по умолчанию:

Iron.defaults

Основные параметры:

{
  encryption: {
    saltBits: 256,
    algorithm: 'aes-256-cbc',
    iterations: 1,
    minPasswordlength: 32
  },
  integrity: {
    saltBits: 256,
    algorithm: 'sha256',
    iterations: 1,
    minPasswordlength: 32
  },
  ttl: 0
}

Ключевые аспекты:

Алгоритм шифрования

  • используется AES-256-CBC
  • обеспечивает симметричное шифрование

Контроль целостности

  • HMAC SHA-256
  • защита от подмены данных

TTL (Time To Live)

  • время жизни токена в миллисекундах
  • 0 означает отсутствие ограничения

Пример с ограничением времени жизни

const options = {
    ...Iron.defaults,
    ttl: 60 * 1000 // 1 минута
};

const sealed = await Iron.seal(data, password, options);

При попытке распаковки после истечения времени:

await Iron.unseal(sealed, password, options);

будет выброшена ошибка.


Обработка ошибок

Iron активно использует исключения. Основные сценарии:

  • неверный пароль
  • повреждённые данные
  • истёкший TTL

Пример безопасной обработки:

try {
    const data = await Iron.unseal(sealed, password, Iron.defaults);
} catch (err) {
    console.error('Ошибка расшифровки:', err.message);
}

Использование в веб-приложениях

Наиболее распространённый сценарий — хранение сессий в cookie:

const session = {
    userId: 42
};

const sealed = await Iron.seal(session, password, Iron.defaults);

// отправка клиенту
response.setHeader('Set-Cookie', `session=${sealed}; HttpOnly`);

Чтение:

const cookie = request.headers.cookie;

const sealed = extractSession(cookie);

const session = await Iron.unseal(sealed, password, Iron.defaults);

Производительность и ограничения

Особенности реализации:

  • асинхронные операции
  • использование криптографических API Node.js
  • зависимость от длины данных

Рекомендации:

  • избегать хранения больших объектов
  • использовать для токенов и небольших payload
  • не применять как замену базе данных

Частые ошибки при первом запуске

Слишком короткий пароль

const password = '123'; // ошибка

Решение: использовать строку ≥ 32 символов.


Несовпадение конфигурации

Iron.seal(data, password, customOptions);
Iron.unseal(sealed, password, Iron.defaults); // ошибка

Настройки должны совпадать.


Повторное использование строки после изменения

Любое изменение строки приводит к ошибке проверки целостности.


Минимальный рабочий пример

const Iron = require('@hapi/iron');

(async () => {
    const password = 'this-is-a-very-secure-password-with-32-chars';

    const data = { hello: 'world' };

    const sealed = await Iron.seal(data, password, Iron.defaults);

    const unsealed = await Iron.unseal(sealed, password, Iron.defaults);

    console.log(unsealed);
})();

Результат:

{ "hello": "world" }

Особенности архитектуры

Iron не хранит состояние:

  • отсутствует серверная сессия
  • вся информация содержится внутри токена

Преимущества:

  • масштабируемость
  • независимость от хранилища
  • простота деплоя

Недостатки:

  • увеличение размера cookie
  • необходимость защиты пароля
  • невозможность отзыва токена без изменения секрета

Практические рекомендации

  • использовать разные пароли для разных сред (dev / prod)
  • хранить секреты в менеджерах конфигурации
  • периодически ротировать ключи
  • не передавать чувствительные данные без необходимости

Проверка корректности установки

Быстрая проверка:

node -e "console.log(require('@hapi/iron') !== undefined)"

Ожидаемый результат:

true

Это подтверждает корректную установку и доступность библиотеки в проекте.