Метод subtle.deriveBits используется для получения
сырых байтов ключевого материала из базового криптографического
ключа и параметров алгоритма. В отличие от deriveKey,
который сразу возвращает объект CryptoKey, этот метод
возвращает ArrayBuffer с бинарными данными, которые затем
можно использовать для собственных схем ключеобразования, HMAC-секретов,
seed-значений или любых других криптографических конструкций.
Ключевая особенность заключается в том, что результатом является не ключевой объект, а именно последовательность битов, что делает метод более низкоуровневым и гибким.
const bits = await crypto.subtle.deriveBits(
algorithm,
baseKey,
length
);
Параметры:
CryptoKey, из
которого выводятся битыВозвращаемое значение:
Promise<ArrayBuffer> — буфер с производными
битамиМетод применяется в ситуациях, когда:
deriveKey)На практике deriveBits чаще всего используется с двумя
типами алгоритмов:
Используется для вычисления общего секрета между двумя сторонами.
const algorithm = {
name: "ECDH",
public: publicKey
};
Здесь baseKey — это приватный ключ локальной стороны, а
public — публичный ключ другой стороны.
Используется для деривации ключей из пароля.
const algorithm = {
name: "PBKDF2",
salt: saltBuffer,
iterations: 100000,
hash: "SHA-256"
};
baseKey в этом случае — ключ, полученный из пароля через
importKey.
Используется для безопасного расширения ключевого материала.
const algorithm = {
name: "HKDF",
salt: saltBuffer,
info: infoBuffer,
hash: "SHA-256"
};
const publicKey = await crypto.subtle.importKey(
"spki",
publicKeyBuffer,
{
name: "ECDH",
namedCurve: "P-256"
},
true,
[]
);
const privateKey = await crypto.subtle.importKey(
"pkcs8",
privateKeyBuffer,
{
name: "ECDH",
namedCurve: "P-256"
},
true,
["deriveBits"]
);
const sharedBits = await crypto.subtle.deriveBits(
{
name: "ECDH",
public: publicKey
},
privateKey,
256
);
Результат sharedBits — это ArrayBuffer
длиной 256 бит, содержащий общий секрет.
const baseKey = await crypto.subtle.importKey(
"raw",
new TextEncoder().encode("user-password"),
"PBKDF2",
false,
["deriveBits"]
);
const salt = crypto.getRandomValues(new Uint8Array(16));
const derivedBits = await crypto.subtle.deriveBits(
{
name: "PBKDF2",
salt: salt,
iterations: 150000,
hash: "SHA-256"
},
baseKey,
256
);
Особенности:
HKDF строится вокруг идеи извлечения и расширения ключа. В
deriveBits чаще используется стадия expansion.
const baseKey = await crypto.subtle.importKey(
"raw",
inputKeyMaterial,
"HKDF",
false,
["deriveBits"]
);
const derived = await crypto.subtle.deriveBits(
{
name: "HKDF",
salt: saltBuffer,
info: new TextEncoder().encode("session-key"),
hash: "SHA-256"
},
baseKey,
256
);
| Характеристика | deriveBits | deriveKey |
|---|---|---|
| Результат | ArrayBuffer | CryptoKey |
| Уровень | низкий | высокий |
| Использование | кастомные схемы | готовые алгоритмы |
| Гибкость | максимальная | ограниченная |
deriveBits даёт полный контроль над тем, что делать с
результатом. Это полезно, когда требуется нестандартная обработка
ключевого материала.
CryptoKey
(["deriveBits"])Результат ArrayBuffer часто преобразуется в удобный
формат:
const bytes = new Uint8Array(derivedBits);
Для использования в криптографических операциях часто применяют:
importKeyПример преобразования в hex:
function toHex(buffer) {
return [...new Uint8Array(buffer)]
.map(b => b.toString(16).padStart(2, "0"))
.join("");
}
Типичная схема использования:
deriveBits используется на первом или втором этапе для
получения сырого материала, который затем становится основой для
симметричного ключа.
Некоторые алгоритмы ожидают длину, кратную 8 битам. Передача нестандартных значений может привести к исключению.
baseKey должен быть создан с нужными usages:
["deriveBits"]
Например, использование ECDH с неподдерживаемой кривой
приведёт к ошибке выполнения.
deriveBits не хранит результат — его нужно сразу
использовать или безопасно сохранять