SubtleCrypto: метод importKey()
Базовый Широко распространённый *
Эта функция хорошо зарекомендовала себя и работает на многих устройствах и версиях браузеров. Она доступна в браузерах с июля 2015 года.
* Некоторые части этой функции могут иметь различный уровень поддержки.
Безопасный контекст: Эта функция доступна только в безопасных контекстах (HTTPS), в некоторых или во всех поддерживающих браузерах.
Примечание: Эта функция доступна в Потоках веб-работы.
Метод importKey() интерфейса SubtleCrypto импортирует ключ: то есть, он принимает на вход ключ во внешнем, переносимом формате и возвращает объект CryptoKey, который можно использовать в API шифрования веб-браузера.
Функция поддерживает несколько форматов импорта; подробности см. в разделе Поддерживаемые форматы.
Синтаксис
importKey(format, keyData, algorithm, extractable, keyUsages)
Параметры
format-
Строка, описывающая формат данных импортируемого ключа. Она может быть одной из следующих:
-
raw: формат Необработанный. -
pkcs8: формат PKCS #8. -
spki: формат SubjectPublicKeyInfo. -
jwk: формат JSON Web Key.
-
keyData-
ArrayBuffer, массив TypedArray,DataViewили объектJSONWebKey, содержащий ключ в указанном формате. algorithm-
Объект, определяющий тип импортируемого ключа и предоставляющий дополнительные параметры, специфичные для алгоритма.
- Для RSASSA-PKCS1-v1_5, RSA-PSS или RSA-OAEP: передайте объект
RsaHashedImportParams. - Для ECDSA или ECDH: передайте объект
EcKeyImportParams. - Для HMAC: передайте объект
HmacImportParams. - Для AES-CTR, AES-CBC, AES-GCM и AES-KW: передайте строку, идентифицирующую алгоритм, или объект вида
{ name: ALGORITHM }, гдеALGORITHM— имя алгоритма. - Для PBKDF2: передайте строку
PBKDF2или объект вида{ name: "PBKDF2" }. - Для HKDF: передайте строку
HKDFили объект вида{ name: "HKDF" }. - Для Ed25519: передайте строку
Ed25519или объект вида{ name: "Ed25519" }. - Для X25519: передайте строку
X25519или объект вида{ name: "X25519" }.
- Для RSASSA-PKCS1-v1_5, RSA-PSS или RSA-OAEP: передайте объект
extractable-
Логическое значение, указывающее, будет ли возможно экспортировать ключ с помощью
SubtleCrypto.exportKey()илиSubtleCrypto.wrapKey(). keyUsages-
Array, указывающий, что можно делать с ключом. Возможные значения массива:-
encrypt: ключ может использоваться для шифрования сообщений. -
decrypt: ключ может использоваться для дешифрования сообщений. -
sign: ключ может использоваться для подписи сообщений. -
verify: ключ может использоваться для проверки подписей. -
deriveKey: ключ может использоваться для вывода нового ключа. -
deriveBits: ключ может использоваться для вывода бит. -
wrapKey: ключ может использоваться для заворачивания ключа. -
unwrapKey: ключ может использоваться для разворачивания ключа.
-
Возвращаемое значение
Исключения
Обещание отклоняется, когда возникает одно из следующих исключений:
-
SyntaxErrorDOMException -
Возникает, когда
keyUsagesпуст, но раскодированный ключ имеет типsecretилиprivate. TypeError-
Возникает при попытке использовать неверный формат или если
keyDataне подходит для этого формата.
Поддерживаемые форматы
Этот API поддерживает четыре разных формата импорта/экспорта ключей: Необработанный, PKCS #8, SubjectPublicKeyInfo и JSON Web Key.
Необработанный
Этот формат можно использовать для импорта или экспорта секретных ключей AES или HMAC, а также открытых ключей кривых Эллиптических кривых.
В этом формате ключ предоставляется в виде ArrayBuffer, содержащего сырые байты ключа.
PKCS #8
Этот формат можно использовать для импорта или экспорта закрытых ключей RSA или Эллиптических кривых.
Формат PKCS #8 определен в RFC 5208 с использованием ASN.1 обозначения:
PrivateKeyInfo ::= SEQUENCE {
version Version,
privateKeyAlgorithm PrivateKeyAlgorithmIdentifier,
privateKey PrivateKey,
attributes [0] IMPLICIT Attributes OPTIONAL }
Метод importKey() ожидает получения этого объекта в виде ArrayBuffer, содержащего DER-кодированный вид PrivateKeyInfo. DER — это набор правил для кодирования структур ASN.1 в двоичный вид.
Вероятнее всего, вы встретите этот объект в формате PEM. Формат PEM — это способ кодирования двоичных данных в ASCII. Он состоит из заголовка и футера, а между ними — base64-кодированные двоичные данные. PEM-кодированный PrivateKeyInfo выглядит так:
-----BEGIN PRIVATE KEY----- MIG2AgEAMBAGByqGSM49AgEGBSuBBAAiBIGeMIGbAgEBBDAU9BD0jxDfF5OV380z 9VIEUN2W5kJDZ3hbuaDenCxLiAMsoquKTfFaou71eLdN0TShZANiAARMUhCee/cp xmjGc1roj0D0k6VlUqtA+JVCWigXcIAukOeTHCngZDKCrD4PkXDBvbciJdZKvO+l ml2FIkoovZh/8yeTKmjUMb804g6OmjUc9vVojCRV0YdaSmYkkJMJbLg= -----END PRIVATE KEY-----
Чтобы преобразовать его в формат, который может принять importKey(), вам необходимо выполнить два действия:
- декодировать base64 часть между заголовком и футером, используя
Window.atob(). - преобразовать полученную строку в
ArrayBuffer.
См. раздел Примеры для получения более конкретных указаний.
SubjectPublicKeyInfo
Этот формат можно использовать для импорта или экспорта открытых ключей RSA или Эллиптических кривых.
SubjectPublicKey определен в RFC 5280, раздел 4.1 с использованием ASN.1 обозначения:
SubjectPublicKeyInfo ::= SEQUENCE {
algorithm AlgorithmIdentifier,
subjectPublicKey BIT STRING }
Как и в случае с PKCS #8, метод importKey() ожидает получения этого объекта в виде ArrayBuffer, содержащего DER-кодированный вид SubjectPublicKeyInfo.
Опять же, вы, скорее всего, встретите этот объект в формате PEM. PEM-кодированный SubjectPublicKeyInfo выглядит так:
-----BEGIN PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3j+HgSHUnc7F6XzvEbD0 r3M5JNy+/kabiJVu8IU1ERAl3Osi38VgiMzjDBDOrFxVzNNzl+SXAHwXIV5BHiXL CQ6qhwYsDgH6OqgKIwiALra/wNH4UHxj1Or/iyAkjHRR/kGhUtjyVCjzvaQaDpJW 2G+syd1ui0B6kJov2CRUWiPwpff8hBfVWv8q9Yc2yD5hCnykVL0iAiyn+SDAk/rv 8dC5eIlzCI4efUCbyG4c9O88Qz7bS14DxSfaPTy8P/TWoihVVjLaDF743LgM/JLq CDPUBUA3HLsZUhKm3BbSkd7Q9Ngkjv3+yByo4/fL+fkYRa8j9Ypa2N0Iw53LFb3B gQIDAQAB -----END PUBLIC KEY-----
Точно так же, как и с PKCS #8, для преобразования этого в формат, который может принять importKey(), необходимо сделать следующее:
- декодировать base64 часть между заголовком и футером, используя
Window.atob(). - преобразовать полученную строку в
ArrayBuffer.
См. раздел Примеры для получения более конкретных указаний.
JSON Web Key
Формат JSON Web Key можно использовать для импорта или экспорта открытых или закрытых ключей RSA или Эллиптических кривых, а также секретных ключей AES и HMAC.
Формат JSON Web Key определен в RFC 7517. Он описывает способ представления открытых, закрытых и секретных ключей в виде JSON-объектов.
JSON Web Key может выглядеть примерно так (это закрытый ключ EC):
{
"crv": "P-384",
"d": "wouCtU7Nw4E8_7n5C1-xBjB4xqSb_liZhYMsy8MGgxUny6Q8NCoH9xSiviwLFfK_",
"ext": true,
"key_ops": ["sign"],
"kty": "EC",
"x": "SzrRXmyI8VWFJg1dPUNbFcc9jZvjZEfH7ulKI1UkXAltd7RGWrcfFxqyGPcwu6AQ",
"y": "hHUag3OvDzEr0uUQND4PXHQTXP5IDGdYhJhL-WLKjnGjQAw0rNGy5V29-aV-yseW"
};
Примеры
Примечание: Вы можете попробовать примеры на GitHub.
Прямой импорт
В этом примере импортируется ключ AES из ArrayBuffer, содержащего сырые байты для использования. Полный код см. на GitHub.
const rawKey = window.crypto.getRandomValues(new Uint8Array(16));
/*
Import an AES secret key from an ArrayBuffer containing the raw bytes.
Takes an ArrayBuffer string containing the bytes, and returns a Promise
that will resolve to a CryptoKey representing the secret key.
*/
function importSecretKey(rawKey) {
return window.crypto.subtle.importKey("raw", rawKey, "AES-GCM", true, [
"encrypt",
"decrypt",
]);
}
Импорт PKCS #8
В этом примере импортируется закрытый ключ подписи RSA из закодированного PEM объекта PKCS #8. Полный код см. на GitHub.
/*
Convert a string into an ArrayBuffer
from https://developers.google.com/web/updates/2012/06/How-to-convert-ArrayBuffer-to-and-from-String
*/
function str2ab(str) {
const buf = new ArrayBuffer(str.length);
const bufView = new Uint8Array(buf);
for (let i = 0, strLen = str.length; i < strLen; i++) {
bufView[i] = str.charCodeAt(i);
}
return buf;
}
const pemEncodedKey = `-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDD0tPV/du2vftjvXj1t/gXTK39sNBVrOAEb/jKzXae+Xa0H+3LhZaQIQNMfACiBSgIfZUvEGb+7TqXWQpoLoFR/R7MvGWcSk98JyrVtveD8ZmZYyItSY7m2hcasqAFiKyOouV5vzyRe87/lEyzzBpF3bQQ4IDaQu+K9Hj5fKuU6rrOeOhsdnJc+VdDQLScHxvMoLZ9Vtt+oK9J4/tOLwr4CG8khDlBURcBY6gPcLo3dPU09SW+6ctX2cX4mkXx6O/0mmdTmacr/vu50KdRMleFeZYOWPAEhhMfywybTuzBiPVIZVP8WFCSKNMbfi1S9A9PdBqnebwwHhX3/hsEBt2BAgMBAAECggEABEI1P6nf6Zs7mJlyBDv+Pfl5rjL2cOqLy6TovvZVblMkCPpJyFuNIPDK2tK2i897ZaXfhPDBIKmllM2Hq6jZQKB110OAnTPDg0JxzMiIHPs32S1d/KilHjGff4Hjd4NXp1l1Dp8BUPOllorR2TYm2x6dcCGFw9lhTr8O03Qp4hjn84VjGIWADYCk83mgS4nRsnHkdiqYnWx1AjKlY51yEK6RcrDMi0Th2RXrrINoC35sVv+APt2rkoMGi52RwTEseA1KZGFrxjq61ReJif6p2VXEcvHeX6CWLx014LGk43z6Q28P6HgeEVEfIjyqCUea5Du/mYb/QsRSCosXLxBqwQKBgQD1+fdC9ZiMrVI+km7Nx2CKBn8rJrDmUh5SbXn2MYJdrUd8bYNnZkCgKMgxVXsvJrbmVOrby2txOiqudZkk5mD3E5O/QZWPWQLgRu8ueYNpobAX9NRgNfZ7rZD+81vh5MfZiXfuZOuzv29iZhU0oqyZ9y75eHkLdrerNkwYOe5aUQKBgQDLzapDi1NxkBgsj9iiO4KUa7jvD4JjRqFy4Zhj/jbQvlvM0F/uFp7sxVcHGx4r11C+6iCbhX4u+Zuu0HGjT4d+hNXmgGyxR8fIUVxOlOtDkVJa5sOBZK73/9/MBeKusdmJPRhalZQfMUJRWIoEVDMhfg3tW/rBj5RYAtP2dTVUMQKBgDs8yr52dRmT+BWXoFWwaWB0NhYHSFz/c8v4D4Ip5DJ5M5kUqquxJWksySGQa40sbqnD05fBQovPLU48hfgr/zghn9hUjBcsoZOvoZR4sRw0UztBvA+7jzOz1hKAOyWIulR6Vca0yUrNlJ6G5R56+sRNkiOETupi2dLCzcqb0PoxAoGAZyNHvTLvIZN4iGSrjz5qkM4LIwBIThFadxbv1fq6pt0O/BGf2o+cEdq0diYlGK64cEVwBwSBnSg4vzlBqRIAUejLjwEDAJyA4EE8Y5A9l04dzV7nJb5cRak6CrgXxay/mBJRFtaHxVlaZGxYPGSYE6UFS0+3EOmmevvDZQBf4qECgYEA0ZF6Vavz28+8wLO6SP3w8NmpHk7K9tGEvUfQ30SgDx4G7qPIgfPrbB4OP/E0qCfsIImi3sCPpjvUMQdVVZyPOIMuB+rV3ZOxkrzxEUOrpOpR48FZbL7RN90yRQsAsrp9e4iv8QwB3VxLe7X0TDqqnRyqrc/osGzuS2ZcHOKmCU8=
-----END PRIVATE KEY-----`;
/*
Import a PEM encoded RSA private key, to use for RSA-PSS signing.
Takes a string containing the PEM encoded key, and returns a Promise
that will resolve to a CryptoKey representing the private key.
*/
function importPrivateKey(pem) {
// fetch the part of the PEM string between header and footer
const pemHeader = "-----BEGIN PRIVATE KEY-----";
const pemFooter = "-----END PRIVATE KEY-----";
const pemContents = pem.substring(
pemHeader.length,
pem.length - pemFooter.length - 1,
);
// base64 decode the string to get the binary data
const binaryDerString = window.atob(pemContents);
// convert from a binary string to an ArrayBuffer
const binaryDer = str2ab(binaryDerString);
return window.crypto.subtle.importKey(
"pkcs8",
binaryDer,
{
name: "RSA-PSS",
hash: "SHA-256",
},
true,
["sign"],
);
}
Импорт SubjectPublicKeyInfo
В этом примере импортируется открытый ключ шифрования RSA из закодированного PEM объекта SubjectPublicKeyInfo. Полный код см. на GitHub.
// from https://developers.google.com/web/updates/2012/06/How-to-convert-ArrayBuffer-to-and-from-String
function str2ab(str) {
const buf = new ArrayBuffer(str.length);
const bufView = new Uint8Array(buf);
for (let i = 0, strLen = str.length; i < strLen; i++) {
bufView[i] = str.charCodeAt(i);
}
return buf;
}
const pemEncodedKey = `-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAy3Xo3U13dc+xojwQYWoJLCbOQ5fOVY8LlnqcJm1W1BFtxIhOAJWohiHuIRMctv7dzx47TLlmARSKvTRjd0dF92jx/xY20Lz+DXp8YL5yUWAFgA3XkO3LSJgEOex10NB8jfkmgSb7QIudTVvbbUDfd5fwIBmCtaCwWx7NyeWWDb7A9cFxj7EjRdrDaK3ux/ToMLHFXVLqSL341TkCf4ZQoz96RFPUGPPLOfvN0x66CM1PQCkdhzjE6U5XGE964ZkkYUPPsy6Dcie4obhW4vDjgUmLzv0z7UD010RLIneUgDE2FqBfY/C+uWigNPBPkkQ+Bv/UigS6dHqTCVeD5wgyBQIDAQAB
-----END PUBLIC KEY-----`;
function importRsaKey(pem) {
// fetch the part of the PEM string between header and footer
const pemHeader = "-----BEGIN PUBLIC KEY-----";
const pemFooter = "-----END PUBLIC KEY-----";
const pemContents = pem.substring(
pemHeader.length,
pem.length - pemFooter.length - 1,
);
// base64 decode the string to get the binary data
const binaryDerString = window.atob(pemContents);
// convert from a binary string to an ArrayBuffer
const binaryDer = str2ab(binaryDerString);
return window.crypto.subtle.importKey(
"spki",
binaryDer,
{
name: "RSA-OAEP",
hash: "SHA-256",
},
true,
["encrypt"],
);
}
Импорт JSON Web Key
Этот код импортирует закрытый ключ подписи ECDSA, используя объект JSON Web Key, представляющий его. Полный код см. на GitHub.
const jwkEcKey = {
crv: "P-384",
d: "wouCtU7Nw4E8_7n5C1-xBjB4xqSb_liZhYMsy8MGgxUny6Q8NCoH9xSiviwLFfK_",
ext: true,
key_ops: ["sign"],
kty: "EC",
x: "SzrRXmyI8VWFJg1dPUNbFcc9jZvjZEfH7ulKI1UkXAltd7RGWrcfFxqyGPcwu6AQ",
y: "hHUag3OvDzEr0uUQND4PXHQTXP5IDGdYhJhL-WLKjnGjQAw0rNGy5V29-aV-yseW",
};
/*
Import a JSON Web Key format EC private key, to use for ECDSA signing.
Takes an object representing the JSON Web Key, and returns a Promise
that will resolve to a CryptoKey representing the private key.
*/
function importPrivateKey(jwk) {
return window.crypto.subtle.importKey(
"jwk",
jwk,
{
name: "ECDSA",
namedCurve: "P-384",
},
true,
["sign"],
);
}
Спецификации
Совместимость с браузерами
| Рабочие столы | Мобильные устройства | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|
| Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox для Android | Opera Android | Safari на iOS | Samsung Internet | WebView Android | |
importKey |
37 | 7912–79["Не поддерживается: RSA-PSS, ECDSA, ECDH.", "Не поддерживается: AES-CTR, HKDF, PBKDF2."] |
34 | 24 | 7 | 37 | 34 | 24 | 7 | 3.0 | 37 |
ed25519 |
113 | 113 | 129 | 99 | 17 | 113 | 129 | Нет | 17 | Нет | Нет |
x25519 |
133 | 133 | 130 | Нет | 17 | 133 | 130 | Нет | 17 | Нет | 133 |
См. также
© 2005–2024 MDN contributors.
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.
https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/importKey