Метод SubtleCrypto.exportKey() используется для экспорта
криптографического ключа из внутреннего представления Web Crypto API в
внешний формат, пригодный для хранения, передачи или последующего
импорта через SubtleCrypto.importKey(). Экспорт возможен
только для ключей, созданных или импортированных с флагом
extractable: true.
Экспортируемый ключ преобразуется в один из стандартных форматов,
поддерживаемых API: raw, pkcs8,
spki, jwk. Выбор формата зависит от типа ключа
и сценария использования.
Метод вызывается на объекте crypto.subtle:
const exportedKey = await crypto.subtle.exportKey(format, key);
Параметры:
format — строка, определяющая формат экспортаkey — объект CryptoKey, подлежащий
экспортуВозвращаемое значение:
Promise:
ArrayBuffer (для raw, pkcs8,
spki)JsonWebKey (для jwk)Ключ может быть экспортирован только при соблюдении следующих условий:
extractable установлено в
trueПопытка экспортировать неэкспортируемый ключ приводит к ошибке
InvalidAccessError.
Используется для симметричных ключей (например, AES).
const keyData = await crypto.subtle.exportKey("raw", key);
Возвращает ArrayBuffer, содержащий «сырые» байты
ключа.
Применяется для:
Особенности:
Формат, представляющий ключ в виде JSON-объекта.
const jwk = await crypto.subtle.exportKey("jwk", key);
Результат:
{
"kty": "RSA",
"n": "...",
"e": "...",
"alg": "RS256",
"ext": true,
"key_ops": ["verify"]
}
Поддерживается для:
Особенности:
Используется для экспорта приватных ключей асимметричной криптографии.
const pkcs8 = await crypto.subtle.exportKey("pkcs8", privateKey);
Возвращает ArrayBuffer в формате ASN.1 DER.
Поддерживается для:
Особенности:
Используется для экспорта публичных ключей.
const spki = await crypto.subtle.exportKey("spki", publicKey);
Возвращает ArrayBuffer в формате SubjectPublicKeyInfo
(X.509).
Применяется для:
Особенности:
const key = await crypto.subtle.generateKey(
{
name: "AES-GCM",
length: 256
},
true,
["encrypt", "decrypt"]
);
const rawKey = await crypto.subtle.exportKey("raw", key);
console.log(new Uint8Array(rawKey));
const keyPair = await crypto.subtle.generateKey(
{
name: "RSA-OAEP",
modulusLength: 2048,
publicExponent: new Uint8Array([1, 0, 1]),
hash: "SHA-256"
},
true,
["encrypt", "decrypt"]
);
const publicJwk = await crypto.subtle.exportKey("jwk", keyPair.publicKey);
const privateJwk = await crypto.subtle.exportKey("jwk", keyPair.privateKey);
const privateKeyPkcs8 = await crypto.subtle.exportKey(
"pkcs8",
keyPair.privateKey
);
const base64 = btoa(
String.fromCharCode(...new Uint8Array(privateKeyPkcs8))
);
const publicKeySpki = await crypto.subtle.exportKey(
"spki",
keyPair.publicKey
);
Ключевой параметр при создании ключа:
crypto.subtle.generateKey(
algorithm,
extractable,
keyUsages
);
Если extractable установлен в false,
то:
exportKey() всегда выбрасывает исключение| Тип ключа | raw | jwk | spki | pkcs8 |
|---|---|---|---|---|
| AES | ✔ | ✔ | ✖ | ✖ |
| HMAC | ✔ | ✔ | ✖ | ✖ |
| RSA public | ✖ | ✔ | ✔ | ✖ |
| RSA private | ✖ | ✔ | ✖ | ✔ |
| EC public | ✖ | ✔ | ✔ | ✖ |
| EC private | ✖ | ✔ | ✖ | ✔ |
InvalidAccessError
extractable: false)NotSupportedError
DataError
Часто экспортированные ключи требуют преобразования:
ArrayBuffer → Base64 (для хранения)JWK → JSON.stringifyPKCS#8/SPKI → PEM форматПример преобразования в Base64:
function arrayBufferToBase64(buffer) {
return btoa(String.fromCharCode(...new Uint8Array(buffer)));
}
Экспортированные ключи почти всегда используются вместе с импортом:
const exported = await crypto.subtle.exportKey("jwk", key);
const imported = await crypto.subtle.importKey(
"jwk",
exported,
algorithm,
true,
["encrypt"]
);
Эта связка обеспечивает:
Экспорт ключей является критической операцией с точки зрения безопасности:
extractable: true только при
необходимости