Метод crypto.subtle.decrypt() в Web Crypto API выполняет
асимметричное или симметричное расшифрование данных, в зависимости от
выбранного алгоритма. Для схемы RSA-OAEP он применяется с приватным
ключом и строго определённой конфигурацией параметров, соответствующей
стандарту OAEP (Optimal Asymmetric Encryption Padding).
RSA-OAEP используется для безопасного расшифрования данных,
зашифрованных соответствующим публичным ключом. Основная идея
заключается в том, что шифрование выполняется вне браузера или на
стороне отправителя, а расшифрование — в среде, где доступен приватный
ключ, импортированный в CryptoKey.
crypto.subtle.decrypt(
algorithm,
key,
data
)
Параметры:
algorithm — объект конфигурации алгоритмаkey — приватный ключ типа CryptoKeydata — зашифрованные данные в формате
ArrayBufferВозвращаемое значение:
Promise<ArrayBuffer> с расшифрованным
содержимымДля RSA-OAEP используется объект следующего вида:
{
name: "RSA-OAEP",
label: ArrayBuffer | Uint8Array (необязательный параметр)
}
Обязательно указывается строка:
"RSA-OAEP"
label используется как дополнительная аутентифицируемая
информация (AAD). Если при шифровании использовалась метка, она должна
совпадать при расшифровании.
ArrayBufferUint8Arrayundefined)Несовпадение label приводит к ошибке расшифрования.
Метод subtle.decrypt для RSA-OAEP требует приватный
ключ:
CryptoKey {
type: "private",
algorithm: {
name: "RSA-OAEP",
hash: { name: "SHA-256" }
},
extractable: false,
usages: ["decrypt"]
}
Ключ должен быть импортирован или сгенерирован через
crypto.subtle.generateKey().
Приватный ключ чаще всего импортируется в формате PKCS#8:
const privateKey = await crypto.subtle.importKey(
"pkcs8",
pemBuffer,
{
name: "RSA-OAEP",
hash: "SHA-256"
},
false,
["decrypt"]
);
Ключевой момент — обязательное совпадение параметра hash
с тем, который использовался при шифровании.
Типовой процесс RSA-OAEP-дешифрования состоит из нескольких этапов:
crypto.subtle.decryptArrayBufferconst decryptedBuffer = await crypto.subtle.decrypt(
{
name: "RSA-OAEP"
},
privateKey,
encryptedData
);
const decoder = new TextDecoder();
const decryptedText = decoder.decode(decryptedBuffer);
Если при шифровании использовалась метка:
const algorithm = {
name: "RSA-OAEP",
label: new TextEncoder().encode("context-1")
};
то при расшифровании она должна быть идентичной:
const decrypted = await crypto.subtle.decrypt(
{
name: "RSA-OAEP",
label: new TextEncoder().encode("context-1")
},
privateKey,
encryptedData
);
Несовпадение байтового представления label приводит к
ошибке OperationError.
Метод возвращает Promise, который может быть отклонён
при следующих условиях:
Типичная ошибка:
OperationError
Она является универсальной и не раскрывает деталей, что соответствует модели безопасности Web Crypto API.
RSA-OAEP в Web Crypto API использует гибридную схему:
Поддерживаемые хэш-алгоритмы:
Современные реализации используют SHA-256 как базовый стандарт.
data в subtle.decrypt должен быть строго
ArrayBuffer.
Часто данные приходят в виде Base64:
function base64ToArrayBuffer(base64) {
const binary = atob(base64);
const bytes = new Uint8Array(binary.length);
for (let i = 0; i < binary.length; i++) {
bytes[i] = binary.charCodeAt(i);
}
return bytes.buffer;
}
Расшифрованный результат также возвращается как
ArrayBuffer. Для текстовых данных используется
TextDecoder:
const text = new TextDecoder("utf-8").decode(decryptedBuffer);
Для бинарных данных результат может использоваться напрямую без декодирования.
Ключ RSA-OAEP должен быть создан с тем же hash, что и
при шифровании.
hash: "SHA-256"
Любое несоответствие делает расшифрование невозможным.
TypeError
возникает при передаче:
CryptoKey"decrypt"RSA-OAEP чувствителен к изменению байтов. Даже один изменённый байт приводит к полной невозможности расшифрования.
RSA-OAEP считается криптографически стойким при корректной реализации:
Ключевые требования:
Web Crypto API накладывает ряд ограничений:
extractable: falseasync function decryptRSA(ciphertext, privateKey) {
const encryptedBuffer = base64ToArrayBuffer(ciphertext);
const result = await crypto.subtle.decrypt(
{
name: "RSA-OAEP"
},
privateKey,
encryptedBuffer
);
return new TextDecoder().decode(result);
}
RSA-OAEP в Web Crypto API всегда используется парно:
crypto.subtle.encrypt() с публичным ключомcrypto.subtle.decrypt() с приватным ключомОба метода должны использовать:
namehashlabel (если задан)Несоответствие любой из этих частей делает систему несовместимой.