Генерация и управление ключами

В библиотеке Iron ключи играют центральную роль в процессе шифрования и расшифрования данных. В отличие от простого кодирования, здесь используется модель sealed data, где любой защищённый объект проходит через этапы сериализации, криптографического преобразования и упаковки с проверкой целостности.

Ключ в Iron — это не просто строка пароля. Это структурированный набор параметров, включающий:

  • id ключа (kid) — идентификатор версии
  • password (master secret) — основной секрет для генерации криптографического материала
  • algorithm — алгоритм хэширования и шифрования
  • salt — соль для усиления стойкости
  • iteration count — количество итераций PBKDF2
  • key size — размер ключа шифрования

Ключ в Iron формирует основу всей системы безопасности. Его качество напрямую определяет стойкость защищённых данных к подбору и криптоанализу.


Генерация ключей

Генерация ключей в Iron строится вокруг принципа детерминированного вывода криптографического материала из мастер-пароля. Основная задача — превратить слабый пользовательский секрет в устойчивый криптографический ключ фиксированной длины.

Процесс генерации включает следующие этапы:

1. Подготовка исходного секрета

Мастер-пароль должен обладать достаточной энтропией. В большинстве реализаций рекомендуется использовать минимум 32 байта случайных данных.

2. Использование PBKDF2

Iron применяет PBKDF2 (Password-Based Key Derivation Function 2), который преобразует пароль в ключ:

  • вход: пароль + соль
  • хэш-функция: обычно SHA-256
  • итерации: от 100 000 и выше в современных конфигурациях

K = PBKDF2(P, S, c, dkLen)

где:

  • P — пароль
  • S — соль
  • c — количество итераций
  • dkLen — длина производного ключа

3. Разделение ключевого материала

Сгенерированный поток байтов разделяется на несколько частей:

  • ключ шифрования (encryption key)
  • ключ подписи (integrity key)

Это обеспечивает разделение ответственности: шифрование и проверка целостности не используют один и тот же секрет.

4. Кодирование результата

Готовый ключ сериализуется в структуру, которая может храниться в конфигурации или передаваться в runtime:

{
  id: "v1",
  encryption: "...",
  integrity: "...",
  algorithm: "aes-256-cbc",
  salt: "...",
  iterations: 100000
}

Управление ключами

Управление ключами в Iron выходит за рамки простой генерации. Это жизненный цикл криптографического материала, включающий создание, хранение, ротацию и отзыв.

Хранение ключей

Ключи не должны храниться в открытом виде в коде. Основные практики:

  • использование переменных окружения
  • хранение в секрет-менеджерах (Vault, AWS Secrets Manager)
  • разделение ключей между окружениями (dev/stage/prod)

Особое внимание уделяется предотвращению утечек через логирование.


Версионирование ключей

Iron поддерживает концепцию множественных ключей. Это позволяет:

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

Каждый ключ имеет уникальный идентификатор kid.

При шифровании данные маркируются текущим активным ключом:

sealed.kid = "v3";

При расшифровке система выбирает соответствующий ключ из набора доступных.


Ротация ключей

Ротация — критически важный процесс в долгосрочной эксплуатации системы.

Причины ротации:

  • компрометация ключа
  • плановое обновление безопасности
  • изменение криптографических стандартов
  • снижение риска долгосрочного brute-force

Модель ротации в Iron:

  1. Добавление нового ключа в список активных
  2. Назначение его как ключа по умолчанию
  3. Постепенное расшифрование старых данных
  4. Опциональная перешифровка при записи

Система не требует немедленной миграции всех данных.


Структура ключевого набора

Типичная конфигурация ключей:

const keys = [
  {
    id: "v1",
    password: process.env.KEY_V1,
    algorithm: "sha256",
    salt: "static-salt-1",
    iterations: 100000
  },
  {
    id: "v2",
    password: process.env.KEY_V2,
    algorithm: "sha256",
    salt: "static-salt-2",
    iterations: 200000
  }
];

Последний элемент массива обычно считается активным.


Привязка ключей к данным

Каждый зашифрованный объект содержит метаданные:

  • идентификатор ключа
  • версия алгоритма
  • параметры шифрования

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

Пример структуры sealed-данных:

{
  sealed: "...",
  mac: "...",
  iv: "...",
  kid: "v2"
}

Проверка целостности

Помимо шифрования, Iron использует механизм MAC (Message Authentication Code), который защищает данные от модификации.

MAC = HMAC_{K_i}(ciphertext)

где:

  • K_i — ключ целостности
  • ciphertext — зашифрованные данные

Любое изменение байта приводит к невозможности расшифровки.


Безопасность генерации ключей

Ключевой фактор безопасности — энтропия источника.

Недопустимые практики:

  • использование коротких паролей
  • генерация ключей вручную
  • повторное использование одного ключа между проектами

Рекомендуемые подходы:

  • криптографически стойкий RNG
  • генерация через crypto.randomBytes
  • использование 256-битных секретов

Разделение окружений

В системах с Iron ключи должны строго разделяться:

  • development — тестовые ключи
  • staging — промежуточные
  • production — изолированные секреты

Перенос ключей между окружениями считается анти-паттерном.


Обновление параметров PBKDF2

Со временем увеличивается вычислительная мощность атакующих систем, поэтому параметры derivation должны усиливаться:

  • увеличение iterations
  • переход на более сильные хэш-функции
  • увеличение длины ключа

Изменение этих параметров требует создания нового ключа версии, а не модификации старого.


Ошибки управления ключами

Типичные ошибки в использовании Iron:

  • хранение ключей в репозитории
  • отсутствие версионирования
  • удаление старых ключей без миграции данных
  • использование одинаковых salt значений
  • игнорирование MAC проверки

Каждая из этих ошибок снижает устойчивость всей системы.


Восстановление и отказоустойчивость

При корректной архитектуре потеря одного ключа не должна приводить к полной потере данных.

Для этого:

  • сохраняется набор исторических ключей
  • используется резервное хранение secrets
  • реализуется fallback-процедура расшифровки

При удалении ключа с активной ролью расшифровка старых данных становится невозможной, что делает ротацию критически чувствительным процессом.


Масштабирование ключевой системы

В высоконагруженных системах количество ключей может достигать десятков и сотен версий. Для оптимизации:

  • используется индексирование по kid
  • кэшируются производные ключи
  • минимизируется количество PBKDF2 вычислений

Это снижает нагрузку на CPU при массовой расшифровке данных.


Совместимость версий

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

  • разные параметры PBKDF2
  • разные алгоритмы шифрования
  • разные схемы упаковки данных

Система выбирает корректный обработчик на основе метаданных sealed-объекта.