При шифровании в SJCL параметры деривации ключа не выносятся в отдельную конфигурацию приложения, а сериализуются непосредственно вместе с шифртекстом. Такой подход устраняет необходимость синхронизации настроек между отправителем и получателем и делает расшифрование самодостаточным процессом: все данные, необходимые для восстановления ключа из пароля, уже содержатся в объекте шифртекста.
Функция sjcl.encrypt(password, data) возвращает
JSON-строку, внутри которой находятся как криптографические параметры,
так и сам зашифрованный текст. Типичная структура выглядит следующим
образом:
iv — вектор инициализацииsalt — криптографическая сольiter — количество итераций KDFks — размер ключа (в битах)ts — размер тега аутентификацииmode — режим шифрования (обычно ccm)adata — дополнительные аутентифицированные данныеcipher — используемый алгоритм (обычно
aes)ct — ciphertext (зашифрованные данные)Параметры деривации ключа напрямую связаны с iter,
salt и ks. Именно их наличие позволяет
восстановить ключ без внешних конфигураций.
salt генерируется случайным образом при каждом
шифровании и служит для защиты от атак с использованием радужных таблиц.
В контексте PBKDF2 (основной KDF в SJCL) соль вводит уникальность даже
при повторяющихся паролях.
Ключевой принцип заключается в том, что одинаковый пароль при разных salt всегда даёт разные производные ключи:
K = (P, S, iter, ks)
где:
Параметр iter играет критическую роль в адаптации
стойкости системы к вычислительным возможностям атакующего. Его
сохранение вместе с шифртекстом решает проблему эволюции
безопасности.
Если бы значение итераций задавалось глобально в приложении, изменение политики безопасности приводило бы к невозможности расшифровать старые данные или необходимости поддерживать несколько конфигураций. Встроенное хранение решает эту проблему:
Поле ks (key size) фиксирует длину ключа, используемого
алгоритмом AES. SJCL поддерживает различные варианты (128, 192, 256
бит), и хранение этого параметра необходимо для корректной интерпретации
битовой длины результата KDF.
Без ks восстановление ключа было бы неоднозначным: один
и тот же пароль и salt могут использоваться для разных уровней
криптостойкости.
В SJCL криптографический формат фактически самодокументируем:
Это приближает формат к принципу «ciphertext carries its own environment».
Такая модель особенно важна для распределённых систем, где:
Со временем параметры KDF неизбежно устаревают. Например, значение
iter, достаточное в момент шифрования, может стать
недостаточным через несколько лет.
Так как параметры встроены в шифртекст, обновление политики безопасности не требует изменения уже сохранённых данных. Вместо этого применяется стратегия:
Таким образом достигается постепенная миграция без массовой перекодировки хранилищ.
Сами по себе параметры salt, iter и
ks не являются секретными. Их раскрытие не снижает
криптографическую стойкость при условии использования стойкого
пароля.
salt должен быть уникальным, но не секретнымiter определяет стоимость атаки, но не раскрывает
парольks фиксирует размер ключа, но не влияет на
энтропиюСекретом остаётся только пароль, из которого строится ключ.
При вызове sjcl.encrypt происходит следующая
последовательность:
saltivИтоговый объект становится полностью автономным контейнером криптографического состояния.
Функция sjcl.decrypt(password, json) извлекает все
параметры автоматически:
Отсутствие внешней конфигурации делает процесс воспроизводимым при любом переносе данных между системами.
Модель хранения параметров деривации внутри шифртекста обеспечивает несколько системных свойств:
Такой подход формирует архитектуру, в которой криптографическая метаинформация становится частью данных, а не частью приложения.