В библиотеке используется симметричное шифрование для «запечатывания» (seal) и «распечатывания» (unseal) данных. Ключевой элемент безопасности — секретный пароль, на основе которого формируются криптографические ключи. При компрометации или плановой смене секретов применяется ротация паролей, позволяющая постепенно переходить на новые ключи без нарушения совместимости с уже выданными токенами.
В механизме Iron допускается использование не одного пароля, а массива секретов. Это создаёт основу для безопасной ротации:
Такой подход обеспечивает обратную совместимость: ранее созданные зашифрованные данные продолжают успешно расшифровываться, даже если используются устаревшие ключи.
При попытке unseal библиотека последовательно проверяет
каждый пароль из списка, пока не найдёт подходящий.
При шифровании всегда используется первый пароль из массива. Это важно: именно он становится текущим активным ключом.
При расшифровке происходит обратный процесс:
Это делает возможным мягкое обновление ключей без массовой реэнкриптации данных.
import Iron from '@hapi/iron';
const passwords = [
'new-super-secret-password',
'old-password-1',
'old-password-2'
];
const data = {
user: 'alice',
role: 'admin'
};
const sealed = await Iron.seal(data, passwords[0], Iron.defaults);
const unsealed = await Iron.unseal(sealed, passwords, Iron.defaults);
В этом примере:
passwords[0] используется для создания нового
зашифрованного объекта;passwords используется для обратного
восстановления данных.Ротация паролей строится на управляемом жизненном цикле ключей.
Новый секрет вводится в систему путем добавления его в начало массива:
const passwords = [
'new-key-v3',
'old-key-v2',
'old-key-v1'
];
После этого все новые данные начинают шифроваться только с
использованием new-key-v3.
Старые ключи не удаляются сразу. Они сохраняются до тех пор, пока остаются данные, зашифрованные с их использованием. После миграции всех токенов старые значения безопасно исключаются.
Типичный цикл ротации:
Если ни один ключ из массива не подходит, операция
unseal завершается ошибкой. Это может означать:
Поэтому порядок ключей имеет критическое значение: чем выше ключ в массиве, тем выше его приоритет.
Перебор ключей линейный, поэтому порядок влияет на производительность.
Рекомендуемая структура массива:
Это минимизирует количество проверок при типичном сценарии использования.
Каждый пароль в Iron не используется напрямую как шифровальный ключ. Из него выводится криптографический материал через алгоритмы хэширования и деривации ключа. Это означает:
Слабые или предсказуемые пароли сводят на нет преимущества ротации.
Механизм множественных ключей особенно важен при:
Старые данные остаются читаемыми, пока присутствует хотя бы один соответствующий ключ.
Список паролей не должен храниться в коде. Обычно он передаётся через:
Пример формирования массива из окружения:
const passwords = process.env.IRON_PASSWORDS.split(',');
Нарушение порядка или стратегии приводит к типичным сбоям:
Особенно критична ситуация, когда новый ключ не ставится на первое место массива.
В распределённых системах каждый узел должен использовать одинаковый порядок ключей. Несогласованность приводит к ситуации, когда один сервер успешно расшифровывает данные, а другой — нет.
Для масштабируемых систем применяются:
Регулярная смена ключей уменьшает риски:
При этом наличие массива ключей позволяет избежать разрушительных миграций и поддерживать непрерывность работы системы.