В библиотеке Iron система паролей не ограничивается простым строковым значением, используемым для шифрования и подписи данных. Архитектура предусматривает более гибкий механизм — использование структурированных, именованных паролей, позволяющих управлять ключами, их версиями и процессом ротации без нарушения совместимости данных.
В классическом варианте пароль в Iron может быть передан как строка:
const password = 'super-secret-key';
Однако в более сложных сценариях применяется объектная форма:
const password = {
id: 'v1',
secret: 'super-secret-key'
};
Такой подход превращает пароль в идентифицируемую сущность, где ключевой элемент — не только секрет, но и его метка.
Поле id выполняет функцию имени версии ключа. Оно
используется для:
При наличии нескольких паролей Iron может определить, какой именно использовался при создании защищённого объекта.
Пример набора ключей:
const passwords = [
{ id: 'v1', secret: 'old-secret-key' },
{ id: 'v2', secret: 'current-secret-key' }
];
При шифровании Iron включает идентификатор пароля в результирующую структуру защищённых данных. Это позволяет при расшифровке автоматически выбрать нужный ключ.
Процесс выглядит следующим образом:
v2id: v2Одно из ключевых преимуществ именованных паролей — возможность безопасной ротации.
Сценарий:
v1, используемый в продакшенеv2v2v1Это устраняет необходимость одномоментного перевыпуска всех защищённых данных.
Если при расшифровке не найден пароль с указанным идентификатором, Iron не может восстановить данные. В этом случае происходит ошибка проверки целостности или невозможность дешифрования.
Типичная ситуация:
const passwords = [
{ id: 'v2', secret: 'current-secret-key' }
];
// данные зашифрованы с v1 → расшифровка невозможна
При передаче массива паролей порядок имеет значение только в
контексте выбора fallback-ключа, если идентификатор отсутствует. Однако
в корректной схеме работы Iron всегда опирается именно на
id.
Если id не указан в зашифрованных данных (например,
устаревший формат), используется первый подходящий пароль из списка.
Система не требует обязательного перехода на именованные пароли. Возможны гибридные сценарии:
const passwords = [
'legacy-secret-key',
{ id: 'v2', secret: 'new-secret-key' }
];
В таком случае строковый пароль считается “безымянным” и используется как fallback для старых данных.
В реальных приложениях версии паролей обычно привязываются к инфраструктурным изменениям:
v1 — первоначальная версия системыv2 — смена алгоритма хранения секретовv3 — миграция на новый контур безопасностиКаждая версия сохраняется до полного отказа от использования данных, зашифрованных соответствующим ключом.
Распространённые проблемы:
id с разными
секретамиЛюбая из этих ошибок приводит к невозможности восстановления данных или к скрытым сбоям при валидации.
Если в списке передано несколько объектов с одинаковым
id, выбирается первый подходящий элемент. Остальные
игнорируются, что может привести к трудно обнаружимым ошибкам при
ротации.
Пример проблемной конфигурации:
const passwords = [
{ id: 'v2', secret: 'first-key' },
{ id: 'v2', secret: 'second-key' }
];
В этом случае фактически активным будет только первый ключ
v2.
В микросервисной архитектуре именованные пароли позволяют синхронизировать криптографические ключи между независимыми компонентами.
Каждый сервис получает одинаковый список:
[
{ id: 'v1', secret: process.env.KEY_V1 },
{ id: 'v2', secret: process.env.KEY_V2 }
]
Это обеспечивает возможность обновления ключей без остановки системы и без необходимости повторного шифрования исторических данных.
Именованные пароли обычно не хранятся в коде напрямую. Они загружаются из:
При этом id остаётся стабильным идентификатором, а
secret может меняться в рамках ротации.
Если в системе добавлен новый ключ, но часть узлов его не получила, возможны следующие сценарии:
idПоэтому внедрение новых именованных паролей требует координированного деплоя.