PBKDF2 (Password-Based Key Derivation Function 2) используется для
преобразования пароля в криптографически стойкий ключ. В Web Crypto API
этот механизм реализован через метод
crypto.subtle.deriveKey и
crypto.subtle.deriveBits, позволяя получать ключи из
низкоэнтропийных источников (паролей) с помощью псевдослучайной функции
на основе HMAC.
PBKDF2 принимает на вход пароль и набор параметров, после чего многократно применяет хеш-функцию, усложняя перебор исходного значения.
Основные компоненты:
Ключевая идея заключается в замедлении вычисления производных ключей, что делает атаки перебором существенно дороже.
Перед использованием PBKDF2 пароль необходимо преобразовать в формат
CryptoKey:
const password = "user-password";
const baseKey = await crypto.subtle.importKey(
"raw",
new TextEncoder().encode(password),
{ name: "PBKDF2" },
false,
["deriveKey", "deriveBits"]
);
Здесь пароль не используется напрямую — он становится материалом для дальнейшего вывода ключа.
Сильная сторона PBKDF2 в гибкости параметров:
salt — уникальное случайное значение для каждого
пользователяiterations — число повторений (обычно десятки или сотни
тысяч)hash — криптографическая хеш-функция (SHA-256, SHA-384,
SHA-512)length — длина итогового ключаПример подготовки соли:
const salt = crypto.getRandomValues(new Uint8Array(16));
Основной способ использования PBKDF2 — получение ключа для симметричного шифрования (например, AES-GCM).
const key = await crypto.subtle.deriveKey(
{
name: "PBKDF2",
salt: salt,
iterations: 150000,
hash: "SHA-256"
},
baseKey,
{ name: "AES-GCM", length: 256 },
false,
["encrypt", "decrypt"]
);
Полученный объект CryptoKey можно использовать для
шифрования данных:
Если требуется не ключ, а просто производное значение:
const derivedBits = await crypto.subtle.deriveBits(
{
name: "PBKDF2",
salt: salt,
iterations: 150000,
hash: "SHA-256"
},
baseKey,
256
);
Результат — ArrayBuffer, который можно использовать
для:
Соль предотвращает использование радужных таблиц и делает одинаковые пароли уникальными на выходе.
Ключевые свойства:
Пример хранения:
salt + iterations + derivedKey
Без соли PBKDF2 теряет значительную часть своей устойчивости к атаке.
Итерации напрямую влияют на стоимость вычисления:
Баланс заключается в том, чтобы замедлить атакующего, но не пользователя.
Web Crypto API поддерживает несколько вариантов:
Наиболее распространённый выбор:
hash: "SHA-256"
PBKDF2 часто используется для серверной и клиентской совместимости:
Важно: сам пароль никогда не сохраняется.
Несмотря на универсальность, существуют ограничения:
PBKDF2 остаётся стандартом, но имеет конкурентов:
PBKDF2 чаще применяется там, где требуется совместимость и поддержка браузеров.
Типичная схема использования в Web Crypto API:
Пример использования результата:
const iv = crypto.getRandomValues(new Uint8Array(12));
const encrypted = await crypto.subtle.encrypt(
{
name: "AES-GCM",
iv: iv
},
key,
new TextEncoder().encode("secret data")
);
PBKDF2 не предназначен для хранения паролей в чистом виде, но используется для:
Качество безопасности зависит от:
Каждая из этих ошибок существенно снижает криптостойкость системы.