SubtleCrypto представляет собой основной программный интерфейс для
выполнения криптографических операций в Web Crypto API. Доступ к нему
осуществляется через свойство crypto.subtle, доступное в
глобальном объекте crypto в контексте безопасного
происхождения (HTTPS или localhost).
Все операции SubtleCrypto выполняются асинхронно и возвращают
Promise, а входные и выходные данные представлены в виде
ArrayBuffer или структурированных типов, совместимых с
бинарными представлениями данных JavaScript.
Доступ к криптографическому API осуществляется следующим образом:
const subtle = crypto.subtle;
Ключевая особенность интерфейса заключается в том, что он не предоставляет «сырых» криптографических примитивов в синхронном виде. Все операции выполняются в изолированной среде браузера, что снижает риск утечек ключей и атак через побочные каналы исполнения.
SubtleCrypto не допускает прямого извлечения секретных ключей в виде обычных строк или чисел, если ключ не был явно экспортирован в поддерживаемом формате.
Все методы SubtleCrypto следуют единому принципу:
ArrayBuffer)PromiseТипичная схема:
crypto.subtle.method(algorithm, key, data)
.then(result => {
// обработка результата
});
SubtleCrypto включает несколько основных групп криптографических функций:
Метод digest используется для получения
криптографического хэша:
const data = new TextEncoder().encode("message");
crypto.subtle.digest("SHA-256", data).then(hash => {
console.log(new Uint8Array(hash));
});
Поддерживаемые алгоритмы включают:
Результат всегда возвращается как ArrayBuffer.
Метод generateKey используется для создания симметричных
и асимметричных ключей.
crypto.subtle.generateKey(
{
name: "AES-GCM",
length: 256
},
true,
["encrypt", "decrypt"]
).then(key => {
console.log(key);
});
crypto.subtle.generateKey(
{
name: "RSA-OAEP",
modulusLength: 2048,
publicExponent: new Uint8Array([1, 0, 1]),
hash: "SHA-256"
},
true,
["encrypt", "decrypt"]
);
Результатом для асимметричных алгоритмов является объект
CryptoKeyPair, содержащий публичный и приватный ключи.
Ключи могут быть сериализованы и восстановлены через
importKey и exportKey.
crypto.subtle.exportKey("jwk", key).then(exported => {
console.log(exported);
});
crypto.subtle.importKey(
"jwk",
jwkKey,
{ name: "AES-GCM" },
true,
["encrypt", "decrypt"]
);
Поддерживаемые форматы:
raw — бинарное представлениеspki — публичные ключи X.509pkcs8 — приватные ключиjwk — JSON Web KeyНаиболее распространённый сценарий — использование AES-GCM.
const iv = crypto.getRandomValues(new Uint8Array(12));
const encoded = new TextEncoder().encode("secret data");
crypto.subtle.encrypt(
{
name: "AES-GCM",
iv
},
key,
encoded
).then(ciphertext => {
console.log(new Uint8Array(ciphertext));
});
crypto.subtle.decrypt(
{
name: "AES-GCM",
iv
},
key,
ciphertext
).then(result => {
console.log(new TextDecoder().decode(result));
});
AES-GCM обеспечивает одновременно конфиденциальность и целостность данных.
SubtleCrypto поддерживает цифровые подписи для проверки подлинности данных.
const data = new TextEncoder().encode("document");
crypto.subtle.sign(
{
name: "ECDSA",
hash: "SHA-256"
},
privateKey,
data
);
crypto.subtle.verify(
{
name: "ECDSA",
hash: "SHA-256"
},
publicKey,
signature,
data
);
Результат проверки — логическое значение.
Механизм используется для безопасной передачи ключей через другой криптографический ключ.
crypto.subtle.wrapKey(
"raw",
keyToWrap,
wrappingKey,
{ name: "AES-KW" }
);
crypto.subtle.unwrapKey(
"raw",
wrappedKey,
wrappingKey,
{ name: "AES-KW" },
{ name: "AES-GCM" },
true,
["encrypt", "decrypt"]
);
SubtleCrypto не работает со строками напрямую. Любые данные должны быть преобразованы:
const encoder = new TextEncoder();
const decoder = new TextDecoder();
const bytes = encoder.encode("text");
const text = decoder.decode(bytes);
Ключевое ограничение заключается в том, что бинарные данные всегда
проходят через ArrayBuffer, что исключает неоднозначность
представления.
SubtleCrypto доступен только при выполнении условий:
Также существуют ограничения:
Объекты CryptoKey содержат метаданные:
extractable)Пример структуры:
{
type: "secret",
extractable: false,
algorithm: { name: "AES-GCM" },
usages: ["encrypt", "decrypt"]
}
Поддерживаемые алгоритмы делятся на категории:
Каждый алгоритм требует строгого описания параметров, включая длину ключа, режим работы и хэш-функцию.
Криптографические операции выполняются вне основного потока JavaScript, что снижает влияние на производительность интерфейса, но накладывает особенности:
Операции с большими массивами данных могут требовать значительного времени из-за копирования буферов между контекстами исполнения.
Все криптографические операции оперируют
ArrayBuffer:
Uint8Array используется для представления байтовTextEncoderПример преобразования:
const buffer = new Uint8Array([1, 2, 3]).buffer;