В X.509 сертификате публичный ключ является центральной частью структуры: именно он используется для проверки цифровых подписей, установления TLS-соединений и криптографической верификации данных. В библиотеке Jsrsasign работа с сертификатами реализована через объектную модель X509 и утилиты KEYUTIL, которые позволяют извлекать и преобразовывать ключевые материалы без необходимости взаимодействия с низкоуровневыми криптографическими примитивами.
Сертификат X.509 в Jsrsasign обычно представлен в формате PEM:
-----BEGIN CERTIFICATE-----
MIIC...==
-----END CERTIFICATE-----
Для его обработки используется класс X509:
const cert = new X509();
cert.readCertPEM(pemString);
Метод readCertPEM выполняет парсинг структуры ASN.1,
извлекая основные поля: субъект, издатель, срок действия и, что наиболее
важно, публичный ключ.
Публичный ключ в X.509 хранится в поле
subjectPublicKeyInfo. В зависимости от алгоритма он может
быть:
Jsrsasign абстрагирует эти различия, приводя ключ к унифицированному объекту KEYUTIL.
Основной способ получения публичного ключа — метод
getPublicKey:
const cert = new X509();
cert.readCertPEM(pemString);
const pubKey = cert.getPublicKey();
Результатом является объект ключа Jsrsasign, который можно использовать для:
Альтернативный и более универсальный способ — использование KEYUTIL:
const pubKey = KEYUTIL.getKey(pemString);
Если передан сертификат, функция автоматически извлекает публичный ключ из структуры X.509. Это делает KEYUTIL предпочтительным инструментом в прикладных задачах.
После извлечения ключа часто требуется его сериализация:
const pubKey = cert.getPublicKey();
const pem = KEYUTIL.getPEM(pubKey);
Результат:
-----BEGIN PUBLIC KEY-----
...
-----END PUBLIC KEY-----
Этот формат соответствует стандарту SPKI и используется в большинстве криптографических API.
Если сертификат содержит RSA-ключ, объект будет иметь структуру:
Пример доступа:
const pubKey = cert.getPublicKey();
console.log(pubKey.n.toString(16));
console.log(pubKey.e.toString(16));
Эти значения позволяют выполнять низкоуровневые операции или интеграцию с внешними библиотеками.
В случае эллиптической криптографии ключ содержит параметры кривой:
Пример:
const pubKey = cert.getPublicKey();
console.log(pubKey.curveName);
console.log(pubKey.pubKeyHex);
Jsrsasign автоматически определяет используемую кривую (например, secp256r1).
Перед извлечением ключа важно убедиться в корректности структуры:
const cert = new X509();
cert.readCertPEM(pemString);
if (!cert.getSubjectString()) {
throw new Error("Некорректный сертификат");
}
Ошибки парсинга обычно связаны с:
Jsrsasign позволяет пропустить явное создание X509:
const pubKey = KEYUTIL.getKey(pemString);
Этот метод:
Подходит для обработки потоков сертификатов без дополнительного анализа структуры.
В некоторых сценариях требуется совместимость с WebCrypto API:
const pubKey = cert.getPublicKey();
const spkiPem = KEYUTIL.getPEM(pubKey);
Далее PEM может быть импортирован:
crypto.subtle.importKey(
"spki",
pemToArrayBuffer(spkiPem),
{ name: "RSASSA-PKCS1-v1_5", hash: "SHA-256" },
true,
["verify"]
);
Jsrsasign при этом выступает как слой извлечения и конвертации.
После получения ключа можно проверить его свойства:
if (pubKey.type !== "RSA" && pubKey.type !== "EC") {
throw new Error("Неизвестный тип ключа");
}
Также доступна проверка длины ключа:
console.log(pubKey.getKeyLength());
Это важно при работе с политиками безопасности (например, минимум 2048 бит для RSA).
Публичный ключ, полученный из сертификата, используется в следующих задачах:
Jsrsasign позволяет выполнять эти операции без перехода к нативным криптобиблиотекам.
При вызове getPublicKey происходит:
Это обеспечивает единообразный API для разных криптографических алгоритмов.
Если сертификат входит в цепочку:
const x509 = new X509();
x509.readCertPEM(pemCert);
const pubKey = x509.getPublicKey();
Публичный ключ извлекается независимо от позиции в цепочке. Однако верификация доверия требует дополнительной логики проверки issuer/subject связей, которая в Jsrsasign реализуется отдельно.
Парсинг сертификата и извлечение ключа являются относительно дорогими операциями по сравнению с использованием уже готового KEYUTIL объекта. При массовой обработке сертификатов рационально кэшировать результат:
const cache = new Map();
function getCachedKey(pem) {
if (!cache.has(pem)) {
cache.set(pem, KEYUTIL.getKey(pem));
}
return cache.get(pem);
}
Такой подход снижает нагрузку при повторных вызовах.