PBKDF2 (Password-Based Key Derivation Function 2) в CryptoJS используется для преобразования пароля в криптографически стойкий ключ с использованием псевдослучайной функции (обычно HMAC) и множества итераций, что существенно усложняет атаки перебором и радужными таблицами.
Основная идея алгоритма заключается в многократном применении хэш-функции к исходному паролю и соли, что позволяет «растянуть» вычисление ключа во времени и тем самым увеличить стоимость каждой попытки подбора.
В библиотеке CryptoJS функция PBKDF2 вызывается через объект
CryptoJS.PBKDF2 и принимает набор параметров, определяющих
качество и безопасность получаемого ключа.
Ключевые элементы алгоритма:
Пример использования:
const key = CryptoJS.PBKDF2('password', 'salt', {
keySize: 256 / 32,
iterations: 10000
});
Пароль выступает исходным секретом, который не должен храниться в открытом виде. Соль — это уникальное значение, добавляемое к паролю для предотвращения атак с использованием заранее вычисленных таблиц.
Соль должна быть:
Отсутствие уникальной соли делает PBKDF2 уязвимым к массовым атакам на одинаковые пароли.
Параметр iterations определяет, сколько раз будет
применена хэш-функция к входным данным.
Математически процесс можно описать как повторное применение функции:
T_i = PRF(T_{i-1})
где PRF — псевдослучайная функция, основанная на HMAC.
Каждое увеличение числа итераций линейно увеличивает время вычисления ключа как для легитимного пользователя, так и для атакующего.
Рост вычислительной сложности можно описать как:
T_{total} = n T_{hash}
где n — число итераций.
Чем выше n, тем дороже становится каждая попытка подбора пароля.
Параметр keySize задаёт длину результирующего ключа в
словах по 32 бита. В CryptoJS это важно учитывать, поскольку API
работает не с байтами напрямую.
Типичные значения:
keySize: 128 / 32 = 4keySize: 256 / 32 = 8Пример:
const key = CryptoJS.PBKDF2('password', 'salt', {
keySize: 8,
iterations: 20000
});
Выбор длины ключа зависит от используемого алгоритма шифрования:
Недостаточная длина ключа снижает криптостойкость даже при большом числе итераций.
CryptoJS использует HMAC как базу PRF. Наиболее распространённые варианты:
Выбор более сильной хэш-функции увеличивает устойчивость к коллизиям и атакам на структуру хэша.
Пример с явным указанием хэша:
const key = CryptoJS.PBKDF2('password', 'salt', {
keySize: 8,
iterations: 50000,
hasher: CryptoJS.algo.SHA256
});
Все параметры PBKDF2 взаимосвязаны и формируют итоговую стойкость системы.
Сводная зависимость:
Общая модель вычислительной стоимости атаки может быть выражена как:
C = N iterations
где N — количество проверяемых паролей.
Одно из наиболее критичных упрощений — использование значений ниже 10 000, что делает алгоритм уязвимым к перебору на GPU.
Использование одной и той же соли для разных пользователей или ключей приводит к снижению энтропии и упрощает анализ атакующему.
Ошибка заключается в указании длины в байтах вместо слов (32-bit words), что приводит к некорректной длине ключа.
Криптографические параметры должны пересматриваться по мере роста вычислительных мощностей атакующих систем.
Для современных приложений типовая конфигурация PBKDF2 выглядит следующим образом:
Пример конфигурации:
const key = CryptoJS.PBKDF2(password, salt, {
keySize: 8,
iterations: 100000,
hasher: CryptoJS.algo.SHA256
});
Такая конфигурация обеспечивает баланс между производительностью и устойчивостью к атакующим сценариям, включая перебор и атаки с использованием специализированного оборудования.