subtle.deriveKey — метод Web Crypto API, предназначенный для получения криптографического ключа на основе исходного ключевого материала. Используется в сценариях, где требуется преобразование общего секрета или пароля в ключ для симметричного шифрования или HMAC.
Метод работает асинхронно и возвращает Promise, который
резолвится в объект CryptoKey. Все операции выполняются
внутри криптографического контекста браузера и не позволяют извлекать
сырой материал ключа при корректных параметрах
(extractable: false).
crypto.subtle.deriveKey(
algorithm,
baseKey,
derivedKeyAlgorithm,
extractable,
keyUsages
)
Объект, описывающий используемый алгоритм деривации ключа. Поддерживаемые варианты:
Каждый алгоритм требует собственную структуру параметров.
{
name: "PBKDF2",
salt: Uint8Array,
iterations: Number,
hash: "SHA-256" | "SHA-384" | "SHA-512"
}
{
name: "HKDF",
salt: Uint8Array,
info: Uint8Array,
hash: "SHA-256" | "SHA-384" | "SHA-512"
}
{
name: "ECDH",
public: CryptoKey
}
Исходный ключ (CryptoKey), из которого выполняется
деривация.
Тип зависит от алгоритма:
importKey с типом "raw" (обычно
пароль в виде байтов)importKeyОписание алгоритма итогового ключа:
{
name: "AES-GCM" | "AES-CBC" | "HMAC",
length: 128 | 192 | 256
}
Для HMAC:
{
name: "HMAC",
hash: "SHA-256",
length: 256
}
Булевое значение, определяющее возможность извлечения ключа:
true — ключ может быть экспортированfalse — ключ остаётся недоступным для экспортаВ криптографических системах безопасности чаще используется
false.
Массив строк, определяющий допустимые операции с ключом:
"encrypt""decrypt""sign""verify""deriveKey""deriveBits""wrapKey""unwrapKey"Promise<CryptoKey>
Результатом является симметрический ключ, пригодный для операций шифрования или вычисления HMAC.
PBKDF2 используется для преобразования пароля в криптографический ключ с усилением стойкости через большое число итераций.
const password = "user-password";
const enc = new TextEncoder();
const baseKey = await crypto.subtle.importKey(
"raw",
enc.encode(password),
"PBKDF2",
false,
["deriveKey"]
);
const salt = crypto.getRandomValues(new Uint8Array(16));
const key = await crypto.subtle.deriveKey(
{
name: "PBKDF2",
salt: salt,
iterations: 100000,
hash: "SHA-256"
},
baseKey,
{
name: "AES-GCM",
length: 256
},
false,
["encrypt", "decrypt"]
);
HKDF применяется для безопасного расширения ключевого материала, например после ECDH.
const enc = new TextEncoder();
const baseKey = await crypto.subtle.importKey(
"raw",
enc.encode("shared-secret"),
"HKDF",
false,
["deriveKey"]
);
const key = await crypto.subtle.deriveKey(
{
name: "HKDF",
salt: crypto.getRandomValues(new Uint8Array(16)),
info: enc.encode("encryption key"),
hash: "SHA-256"
},
baseKey,
{
name: "AES-GCM",
length: 256
},
false,
["encrypt", "decrypt"]
);
infoECDH позволяет двум сторонам вычислить общий секрет, который затем преобразуется в симметрический ключ.
const aliceKeys = await crypto.subtle.generateKey(
{
name: "ECDH",
namedCurve: "P-256"
},
false,
["deriveKey"]
);
const bobKeys = await crypto.subtle.generateKey(
{
name: "ECDH",
namedCurve: "P-256"
},
false,
["deriveKey"]
);
const sharedKey = await crypto.subtle.deriveKey(
{
name: "ECDH",
public: bobKeys.publicKey
},
aliceKeys.privateKey,
{
name: "AES-GCM",
length: 256
},
false,
["encrypt", "decrypt"]
);
"deriveKey"Если ключ импортирован без "deriveKey":
InvalidAccessError
Например, попытка получить AES-GCM ключ из ECDH без корректной
структуры параметров приводит к ошибке OperationError.
subtle.deriveKey опирается на следующие принципы:
extractable: false