HKDF (HMAC-based Extract-and-Expand Key Derivation Function) в Web
Crypto API используется через SubtleCrypto.deriveKey или
SubtleCrypto.deriveBits и представляет собой механизм
получения криптографически стойких ключей из исходного материала.
В объекте алгоритма HKDF всегда задаются три ключевых параметра:
salt, info, hash. Каждый из них
влияет на безопасность, уникальность и контекст получаемого ключа.
Вызов выглядит через конфигурацию алгоритма:
{
name: "HKDF",
hash: "SHA-256",
salt: Uint8Array,
info: Uint8Array
}
Использование происходит в составе deriveKey:
const derivedKey = await crypto.subtle.deriveKey(
{
name: "HKDF",
hash: "SHA-256",
salt: saltBuffer,
info: infoBuffer
},
baseKey,
{ name: "AES-GCM", length: 256 },
false,
["encrypt", "decrypt"]
);
salt — случайное или псевдослучайное значение, которое
добавляется на этапе «extract» в HKDF. Его задача — сделать результат
деривации устойчивым к предвычислениям и атакам на основе словарей.
const salt = crypto.getRandomValues(new Uint8Array(16));
info — контекстная строка или структура данных,
используемая на этапе «expand». Этот параметр не влияет на стойкость
напрямую, но критически важен для разделения ключей по назначению.
ArrayBuffer или
TypedArrayconst info = new TextEncoder().encode("chat encryption key");
info = "encryption" и
info = "integrity"info = "session-12345"info = "client" /
info = "server"Даже при одинаковых salt и исходном ключе различие в
info полностью меняет результат HKDF.
Параметр hash определяет криптографическую хеш-функцию,
используемую внутри HKDF как HMAC-примитив.
Поддерживаемые значения:
"SHA-256""SHA-384""SHA-512"Эти три параметра работают в разных этапах HKDF:
salt участвует в этапе extract (формирование
псевдослучайного ключа)hash определяет криптографический фундамент HMACinfo применяется на этапе expand для генерации
контекстных ключейИзменение любого параметра приводит к полностью другому результату:
const salt = new Uint8Array(16); // плохая практика
Такой подход снижает устойчивость к предвычислениям и делает систему более предсказуемой.
Отсутствие контекстной привязки приводит к ситуации, когда один и тот же ключ используется в разных целях:
info: new Uint8Array(0)
Это увеличивает риск повторного использования ключей в несовместимых протоколах.
Если одна сторона использует SHA-256, а другая SHA-512, результат HKDF будет несовместим, несмотря на совпадение всех остальных параметров.
const baseKey = await crypto.subtle.importKey(
"raw",
new TextEncoder().encode("master secret"),
"HKDF",
false,
["deriveKey"]
);
const salt = crypto.getRandomValues(new Uint8Array(16));
const info = new TextEncoder().encode("encryption key");
const key = await crypto.subtle.deriveKey(
{
name: "HKDF",
hash: "SHA-256",
salt,
info
},
baseKey,
{
name: "AES-GCM",
length: 256
},
false,
["encrypt", "decrypt"]
);
Все параметры HKDF в Web Crypto API должны быть представлены в виде бинарных структур:
salt → ArrayBuffer или
TypedArrayinfo → ArrayBuffer или
TypedArrayTextEncoderОшибки в кодировке часто приводят к несовместимости между клиентами, особенно при различиях в UTF-8 представлении строк.
salt защищает от атак с предварительным
вычислениемinfo обеспечивает разделение контекста и предотвращает
повторное использование ключейhash задаёт уровень криптографической стойкости и
определяет фундамент алгоритмаСовместное использование этих параметров формирует из HKDF инструмент контролируемой и предсказуемой деривации ключей с жёсткой контекстной привязкой