Запрос на подпись сертификата (Certificate Signing Request, CSR) в формате PKCS#10 представляет собой ASN.1-структуру, содержащую открытый ключ и атрибуты субъекта, подписанные приватным ключом. В контексте JavaScript-библиотеки Jsrsasign работа с CSR строится вокруг декодирования ASN.1 и извлечения полей X.500 имени, расширений и криптографической подписи.
Базовая структура CSR включает:
В ASN.1-терминах CSR описывается как:
CertificationRequest ::= SEQUENCE {
certificationRequestInfo CertificationRequestInfo,
signatureAlgorithm AlgorithmIdentifier,
signature BIT STRING
}
Ключевая часть — CertificationRequestInfo, именно она
подписывается приватным ключом и затем проверяется при валидации
CSR.
В библиотеке Jsrsasign основная точка входа для анализа CSR — модуль
KJUR.asn1.csr.CSRUtil.
Парсинг PEM-формата CSR:
const csrPEM = `
-----BEGIN CERTIFICATE REQUEST-----
MIIC...
-----END CERTIFICATE REQUEST-----
`;
const info = KJUR.asn1.csr.CSRUtil.getInfo(csrPEM);
console.log(info);
getInfo выполняет полное декодирование структуры и
возвращает объект с уже интерпретированными полями:
Distinguished Name в CSR представлен в виде X.500 структуры и включает такие поля, как CN, O, OU, C.
Пример извлечения:
const info = KJUR.asn1.csr.CSRUtil.getInfo(csrPEM);
console.log(info.subject.str);
Типичный результат:
CN=example.com, O=Example Corp, C=US
Для более детальной работы можно разобрать структуру по компонентам:
info.subject.array.forEach(rdn => {
console.log(rdn.type, rdn.value);
});
CSR содержит публичный ключ, который можно извлечь и использовать для дальнейшей проверки или генерации сертификата.
const pubKeyObj = KEYUTIL.getKey(info.subjectPublicKeyInfo);
console.log(pubKeyObj);
В зависимости от алгоритма (RSA, EC) объект будет иметь разные методы и параметры:
Одной из ключевых операций является проверка, что CSR действительно подписан соответствующим приватным ключом.
Jsrsasign позволяет выполнить валидацию автоматически:
const isValid = KJUR.asn1.csr.CSRUtil.verify(csrPEM);
console.log(isValid);
Внутри происходит:
certificationRequestInfoЕсли подпись некорректна или CSR был изменён, результат будет
false.
CSR содержит поле signatureAlgorithm, которое определяет
используемый криптографический алгоритм:
Примеры:
Извлечение:
console.log(info.signatureAlgorithm.name);
console.log(info.signatureAlgorithm.param);
Это важно при проверке совместимости с серверной стороной (CA).
Хотя CSR PKCS#10 формально ограничен атрибутами, современные реализации часто используют их для передачи расширений сертификата.
Часто встречается атрибут:
extensionRequest (OID 1.2.840.113549.1.9.14)Пример извлечения:
const attrs = info.attributes;
attrs.forEach(attr => {
console.log(attr.name, attr.value);
});
Если присутствует extensionRequest, внутри могут
быть:
SAN является критически важным расширением, определяющим дополнительные домены или IP-адреса.
const ext = KJUR.asn1.x509.X509Util.getExtInfo(info.attributes);
console.log(ext.subjectAltName);
Пример содержимого:
DNS:example.com, DNS:www.example.com, IP:192.168.1.1
Jsrsasign поддерживает оба формата CSR:
const info = KJUR.asn1.csr.CSRUtil.getInfo(pem);
const hexCSR = hextorstr(PEMtoHex(csrPEM));
const info = KJUR.asn1.csr.CSRUtil.getInfo(hexCSR);
Преобразование особенно важно при работе с API, которые возвращают бинарные данные.
Внутренняя логика CSR предполагает, что подпись создаётся приватным ключом, соответствующим публичному.
Jsrsasign позволяет вручную проверить это через криптографические primitives:
const csr = new KJUR.asn1.csr.CSR();
csr.readCertPEM(csrPEM);
const pubKey = csr.getPublicKey();
const sigValid = csr.verifySignature();
console.log(sigValid);
Часто встречаются следующие проблемы:
Некорректный PEM формат
Несовпадение алгоритмов
Повреждённый ASN.1
Для глубокого анализа можно получить сырой ASN.1 объект:
const csr = new KJUR.asn1.csr.CSR(csrPEM);
const asn1 = csr.getASN1();
console.log(JSON.stringify(asn1, null, 2));
Это позволяет увидеть:
CSR в Jsrsasign часто используется в следующих сценариях:
Типичный поток:
Для RSA ключа:
const key = KEYUTIL.getKey(info.subjectPublicKeyInfo);
console.log(key.n.toString(16)); // modulus
console.log(key.e.toString(16)); // exponent
Для EC:
console.log(key.curveName);
console.log(key.pubKeyHex);
Это позволяет определить параметры криптосистемы до выдачи сертификата.
Перед принятием CSR часто проверяют:
Jsrsasign позволяет собрать все данные в одном объекте и выполнить валидацию без внешних зависимостей.
CSRUtil в Jsrsasign выполняет несколько этапов:
Этот слой абстракции избавляет от необходимости ручного анализа ASN.1 дерева.
Некоторые CSR содержат расширенные атрибуты:
Jsrsasign не всегда интерпретирует их автоматически, но позволяет получить raw значения через ASN.1 дерево и разобрать вручную через OID-маппинг.
info.attributes.forEach(attr => {
console.log(attr.oid, attr.valueHex);
});
Валидация подписи CSR основана на вычислении хеша от
certificationRequestInfo.
Процесс:
hash = H(certificationRequestInfo)
verify(signature, hash, publicKey)
Jsrsasign скрывает эти операции, но логически они соответствуют стандарту PKCS#10 и X.509.
После анализа CSR он может быть использован для создания сертификата:
const cert = new KJUR.asn1.x509.Certificate();
cert.setSubject(info.subject);
cert.setPublicKey(info.subjectPublicKeyInfo);
cert.sign(caPrivateKey, "SHA256withRSA");
CSR здесь выступает источником доверенных параметров субъекта.