PBES2 в контексте JSON Web Encryption (JWE) в библиотеке jose используется как механизм ключевого шифрования на основе пароля. В отличие от асимметричных схем, где ключи основаны на паре публичный/приватный, PBES2 опирается на симметричный секрет — пароль, из которого с помощью функции деривации ключа (KDF) формируется ключ шифрования ключа контента.
PBES2 реализует комбинацию PBKDF2 (Password-Based Key Derivation Function 2) и HMAC для генерации ключа достаточной криптографической стойкости. Основная идея заключается в том, что пароль сам по себе не используется напрямую для шифрования, а преобразуется в ключ через многократные итерации хэширования.
В JWE PBES2 относится к алгоритмам alg (algorithms for
key management). Примеры:
Структура имени:
Таким образом, PBES2 отвечает за получение KEK (Key Encryption Key), а AES-KW используется для обёртки CEK (Content Encryption Key).
Ключевым параметром PBES2 является количество итераций PBKDF2.
Итерации определяют, сколько раз функция хэширования применяется при выводе ключа из пароля:
Формально PBKDF2:
= (P, S, c, )
где:
В библиотеке jose параметр iterations задаётся через
protected header или через опции при шифровании.
Пример:
import { compactEncrypt } from 'jose'
const encoder = new TextEncoder()
const jwe = await new compactEncrypt(
encoder.encode('секретное сообщение')
)
.setProtectedHeader({
alg: 'PBES2-HS256+A128KW',
enc: 'A256GCM'
})
.encrypt(password)
При этом библиотека автоматически генерирует:
В jose можно явно управлять параметрами PBES2 через дополнительные настройки.
Ключевые параметры:
Пример настройки:
import { CompactEncrypt } from 'jose'
const jwe = await new CompactEncrypt(
new TextEncoder().encode('data')
)
.setProtectedHeader({
alg: 'PBES2-HS256+A128KW',
enc: 'A256GCM',
p2c: 200000,
p2s: crypto.getRandomValues(new Uint8Array(16))
})
.encrypt(password)
PBES2 устойчивость напрямую зависит от параметра
p2c.
Упрощённая зависимость:
c
где c — число итераций PBKDF2.
Однако рост безопасности не линейный в практическом смысле. Он ограничен:
В современных реализациях обычно используются значения:
Процесс шифрования выглядит следующим образом:
Генерация случайного CEK (Content Encryption Key)
Генерация salt (p2s)
Применение PBKDF2:
Получение KEK (Key Encryption Key)
Обёртка CEK через AES Key Wrap
Шифрование данных CEK
Формирование JWE структуры
PBKDF2 имеет линейную сложность по числу итераций:
T(c) = O(c)
где c — iterations.
Это означает, что увеличение итераций в 10 раз увеличивает время деривации примерно в 10 раз.
Библиотека jose:
При декодировании:
import { compactDecrypt } from 'jose'
const { plaintext } = await compactDecrypt(jwe, password)
jose:
PBES2 устойчив к:
Но остаётся уязвимым к:
Алгоритм HMAC влияет на стойкость PBKDF2:
Влияние на вычисления:
T _{cost} c
Для современных приложений на jose обычно используется:
При серверных нагрузках возможна адаптация:
PBES2 можно рассматривать как композицию:
= (, , c) + +
где каждая часть отвечает за отдельный слой безопасности: