Библиотека jsrsasign реализует криптографические операции в
JavaScript на уровне пользовательского пространства выполнения, включая
RSA, ECDSA, X.509, CMS и работу с ASN.1 структурами. В отличие от неё
Web Crypto API является встроенным системным интерфейсом браузера,
предоставляющим доступ к нативной криптографии через объект
crypto.subtle.
Ключевое различие заключается в модели представления ключей:
CryptoKey, которые
являются непрозрачными (non-exportable в некоторых режимах)Это различие определяет необходимость промежуточного преобразования данных при совместном использовании.
jsrsasign активно работает с PEM-форматом:
-----BEGIN RSA PRIVATE KEY-----
...
-----END RSA PRIVATE KEY-----
Web Crypto API не принимает PEM напрямую. Для работы требуется импорт
в формате ArrayBuffer и структурированное описание
алгоритма:
crypto.subtle.importKey(
"pkcs8",
arrayBufferKey,
algorithmParameters,
true,
["sign"]
)
Таким образом возникает обязательный слой конвертации:
jsrsasign содержит утилиты для парсинга ASN.1, что позволяет использовать его как промежуточный трансформатор.
RSA ключи в jsrsasign часто представлены через объект
RSAKey:
const rsa = KEYUTIL.getKey(pemPrivateKey);
Для Web Crypto API требуется формат PKCS#8 или SPKI.
Процесс включает несколько этапов:
ArrayBuffersubtle.importKeyПример преобразования:
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;
}
После этого ключ может быть импортирован:
const key = await crypto.subtle.importKey(
"pkcs8",
pemToArrayBuffer(privateKeyPem),
{
name: "RSASSA-PKCS1-v1_5",
hash: "SHA-256"
},
true,
["sign"]
);
jsrsasign может генерировать RSA ключи:
const kp = KEYUTIL.generateKeypair("RSA", 2048);
const privateKeyPem = KEYUTIL.getPEM(kp.prvKeyObj, "PKCS8PRV");
const publicKeyPem = KEYUTIL.getPEM(kp.pubKeyObj);
Далее эти ключи преобразуются для Web Crypto API.
Особенность заключается в том, что jsrsasign генерирует ключи синхронно, тогда как Web Crypto API требует асинхронной модели и может использовать аппаратное ускорение.
jsrsasign:
const sig = new KJUR.crypto.Signature({ alg: "SHA256withRSA" });
sig.init(privateKeyPem);
sig.updateString("data");
const signature = sig.sign();
Web Crypto API:
const signature = await crypto.subtle.sign(
{
name: "RSASSA-PKCS1-v1_5"
},
cryptoKey,
new TextEncoder().encode("data")
);
Основное различие:
ArrayBufferЭто требует дополнительного преобразования при совместном использовании.
Часто возникает сценарий:
Проблема заключается в несовпадении кодировок.
jsrsasign:
const sigHex = signature; // hex string
Web Crypto API ожидает:
ArrayBuffer
Решение — декодирование hex:
function hexToBuffer(hex) {
const buffer = new ArrayBuffer(hex.length / 2);
const view = new Uint8Array(buffer);
for (let i = 0; i < hex.length; i += 2) {
view[i / 2] = parseInt(hex.substr(i, 2), 16);
}
return buffer;
}
jsrsasign использует:
KJUR.crypto.ECDSA
Web Crypto API использует:
{
name: "ECDSA",
namedCurve: "P-256"
}
Ключевая проблема — формат подписи:
При переходе между системами часто требуется декодирование ASN.1 структуры:
jsrsasign предоставляет:
ASN1HEX.parse
Но Web Crypto API ожидает фиксированную бинарную структуру.
jsrsasign имеет полноценный парсер сертификатов:
const cert = new X509();
cert.readCertPEM(pemCert);
Web Crypto API не предоставляет встроенного парсинга X.509, но позволяет импортировать публичный ключ:
crypto.subtle.importKey(
"spki",
spkiBuffer,
{ name: "RSA-PSS", hash: "SHA-256" },
true,
["verify"]
);
Таким образом jsrsasign используется как слой извлечения публичного ключа из сертификата.
const x = new X509();
x.readCertPEM(certPem);
const publicKey = KEYUTIL.getKey(x.getPublicKey());
const spkiPem = KEYUTIL.getPEM(publicKey);
Далее выполняется конвертация PEM → ArrayBuffer.
Типичная схема взаимодействия:
Поток данных:
subtlejsrsasign:
Web Crypto API:
Несовпадение алгоритмов
RSA-PKCS1 vs RSA-PSS приводит к невозможности проверки подписи.
Неверный формат ключа
PKCS#1 вместо PKCS#8 вызывает ошибку DataError.
Проблемы кодировки
Base64URL vs Base64 приводит к некорректной загрузке ключей.
Использование jsrsasign оправдано при:
Web Crypto API предпочтителен при:
На практике обе технологии часто используются совместно в одной архитектуре:
Такой подход позволяет компенсировать ограничения каждой из систем, сохраняя совместимость с внешними криптографическими стандартами и обеспечивая производительность нативного API.