Форматы импорта в Web Crypto API определяют способ передачи ключевого
материала в криптографическое хранилище браузера через
SubtleCrypto.importKey. От выбранного формата зависит
структура входных данных, область применения ключа и совместимость с
внешними системами, включая серверные реализации OpenSSL,
JWT-инфраструктуры и аппаратные криптомодули.
В Web Crypto API ключи не создаются и не используются в «сыром» виде без явного описания формата. Каждый формат отражает конкретную криптографическую модель: симметричное шифрование, асимметричную криптографию или представление ключа в стандартизированном обменном виде.
Формат raw используется исключительно для симметричных
ключей. Он представляет собой необработанную последовательность байтов
без дополнительной структуры, заголовков или метаданных.
Чаще всего raw применяется для алгоритмов, где ключ —
это просто набор случайных байтов фиксированной длины.
Типичные сценарии использования:
Структура данных:
ArrayBuffer или TypedArrayПример импорта симметричного ключа:
const keyData = crypto.getRandomValues(new Uint8Array(32));
const key = await crypto.subtle.importKey(
"raw",
keyData,
{ name: "AES-GCM" },
false,
["encrypt", "decrypt"]
);
Особенности формата:
Ключи raw не используются в асимметричных алгоритмах,
так как не содержат математической структуры (например, модулей или
экспонент).
Формат pkcs8 применяется для импорта приватных
ключей асимметричной криптографии. Это стандартизированная
структура, определённая в спецификации PKCS#8, которая описывает
приватный ключ вместе с алгоритмом его использования.
Чаще всего используется для:
Формат включает:
В WebCrypto передаётся в виде DER-кодированного
ArrayBuffer.
Пример импорта:
const privateKey = await crypto.subtle.importKey(
"pkcs8",
pkcs8Buffer,
{
name: "RSA-PSS",
hash: "SHA-256"
},
false,
["sign"]
);
Структурные особенности:
PEM-представление обычно выглядит так:
-----BEGIN PRIVATE KEY-----
(base64)
-----END PRIVATE KEY-----
При обработке в WebCrypto заголовки и переносы строк удаляются, остаётся чистый бинарный буфер.
Формат spki (Subject Public Key Info) используется для
импорта публичных ключей асимметричной криптографии. Он
является зеркальным по отношению к PKCS#8, но предназначен исключительно
для открытых ключей.
Применяется в:
Структура включает:
Импорт осуществляется через SubtleCrypto.importKey:
const publicKey = await crypto.subtle.importKey(
"spki",
spkiBuffer,
{
name: "RSA-OAEP",
hash: "SHA-256"
},
false,
["encrypt"]
);
Особенности:
PEM-представление:
-----BEGIN PUBLIC KEY-----
(base64)
-----END PUBLIC KEY-----
SPKI часто используется при загрузке ключей из сертификатов, извлечённых из TLS-цепочек.
Формат jwk (JSON Web Key) представляет ключ в виде
JSON-объекта. Это высокоуровневое представление, стандартизированное в
RFC 7517 и активно используемое в веб-экосистеме.
JWK поддерживает как симметричные, так и асимметричные ключи.
Пример RSA ключа:
{
"kty": "RSA",
"e": "AQAB",
"n": "0vx7agoebGcQSuuPiLJXZptN..."
}
Пример симметричного ключа:
{
"kty": "oct",
"k": "GawgguFyGrWKav7AX4VKUg"
}
Импорт:
const key = await crypto.subtle.importKey(
"jwk",
jwkObject,
{
name: "RSA-PSS",
hash: "SHA-256"
},
false,
["sign"]
);
Особенности формата:
kid, use,
alg)Ключевые поля:
kty — тип ключа (RSA, EC, oct)use — назначение (sig, enc)alg — алгоритмext — разрешение на экспортkid — идентификатор ключаВ отличие от PKCS#8 и SPKI, JWK не требует бинарного парсинга ASN.1, что делает его удобным в JavaScript-экосистемах.
Разные форматы связаны с разными классами криптографических ключей:
raw → симметричные ключи (AES, HMAC)pkcs8 → приватные ключи RSA/ECCspki → публичные ключи RSA/ECCjwk → универсальное JSON-представлениеАсимметричная криптография всегда использует пару форматов:
Web Crypto API внутри браузера приводит все форматы к единому криптографическому представлению, независимому от исходного кодирования.
При импорте происходит несколько стадий:
Форматы PKCS#8 и SPKI требуют ASN.1 DER парсинга, что делает их более «низкоуровневыми» по сравнению с JWK.
PKCS#8 и SPKI часто встречаются в PEM-обёртке. Перед импортом выполняется преобразование:
-----BEGIN ...-----ArrayBufferПример преобразования:
function pemToArrayBuffer(pem) {
const base64 = pem
.replace(/-----[^-]+-----/g, "")
.replace(/\s/g, "");
const binary = atob(base64);
const buffer = new ArrayBuffer(binary.length);
const view = new Uint8Array(buffer);
for (let i = 0; i < binary.length; i++) {
view[i] = binary.charCodeAt(i);
}
return buffer;
}
Форматы имеют строгие ограничения:
raw не используется для RSA/ECCpkcs8 не содержит публичной части ключаspki не содержит приватной информацииjwk требует корректного Base64URL кодированияНесовместимость формата и алгоритма приводит к ошибке
DataError.
PKCS#8 и SPKI ориентированы на инфраструктурную совместимость:
JWK ориентирован на веб-приложения:
RAW ориентирован на симметричную криптографию внутри приложения:
При работе с форматами импорта возникают повторяющиеся проблемы:
Каждый формат строго привязан к внутреннему криптографическому представлению и не является взаимозаменяемым без преобразования.
Разделение на raw, pkcs8,
spki, jwk отражает несколько уровней
абстракции:
Эта модель обеспечивает совместимость между: