Именованные пароли

В библиотеке 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 включает идентификатор пароля в результирующую структуру защищённых данных. Это позволяет при расшифровке автоматически выбрать нужный ключ.

Процесс выглядит следующим образом:

  1. Данные шифруются с использованием пароля v2
  2. В зашифрованный объект записывается id: v2
  3. При расшифровке Iron читает идентификатор
  4. Выбирается соответствующий секрет из списка доступных паролей
  5. Выполняется восстановление исходного значения

Поддержка ротации ключей

Одно из ключевых преимуществ именованных паролей — возможность безопасной ротации.

Сценарий:

  • существует ключ v1, используемый в продакшене
  • добавляется новый ключ v2
  • новые данные шифруются с v2
  • старые данные продолжают расшифровываться через v1

Это устраняет необходимость одномоментного перевыпуска всех защищённых данных.

Поведение при отсутствии совпадения id

Если при расшифровке не найден пароль с указанным идентификатором, 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 }
]

Это обеспечивает возможность обновления ключей без остановки системы и без необходимости повторного шифрования исторических данных.

Хранение и управление секретами

Именованные пароли обычно не хранятся в коде напрямую. Они загружаются из:

  • переменных окружения
  • секрет-хранилищ (Vault, AWS Secrets Manager)
  • конфигурационных сервисов

При этом id остаётся стабильным идентификатором, а secret может меняться в рамках ротации.

Поведение при частичном обновлении

Если в системе добавлен новый ключ, но часть узлов его не получила, возможны следующие сценарии:

  • новые данные шифруются с неизвестным для части узлов id
  • старые узлы не могут расшифровать новые данные
  • требуется синхронное обновление конфигурации

Поэтому внедрение новых именованных паролей требует координированного деплоя.