CSR (Certificate Signing Request) в формате PKCS
В библиотеке jsrsasign работа с CSR реализована через объект
KJUR.asn1.csr.CSRUtil, а криптографические операции
опираются на модуль KEYUTIL, RSAKey, а также
хэш-функции и алгоритмы подписи, встроенные в библиотеку.
CSR в PKCS#10 состоит из трёх ключевых компонентов:
Подпись выполняет две функции:
Перед созданием CSR необходимо сформировать асимметрическую пару ключей.
const { KEYUTIL } = KJUR;
// генерация RSA ключа 2048 бит
const kp = KEYUTIL.generateKeypair("RSA", 2048);
const privateKey = kp.prvKeyObj;
const publicKey = kp.pubKeyObj;
В реальных сценариях чаще используется импорт заранее созданного приватного ключа:
const privateKey = KEYUTIL.getKey(pemPrivateKey);
Основной способ создания CSR — использование
KJUR.asn1.csr.CSRUtil.newCSRPEM.
const csrPem = KJUR.asn1.csr.CSRUtil.newCSRPEM({
subject: {
str: "/C=RU/ST=Region/L=City/O=Company/OU=IT/CN=example.com"
},
sbjpubkey: publicKey,
sigalg: "SHA256withRSA",
sbjprvkey: privateKey
});
Ключевые параметры:
subject.str — Distinguished Name в формате X.500sbjpubkey — публичный ключsbjprvkey — приватный ключ для подписи CSRsigalg — алгоритм подписиJsrsasign поддерживает широкий набор алгоритмов:
SHA256withRSASHA384withRSASHA512withRSASHA256withECDSASHA384withECDSAНаиболее распространённый вариант:
sigalg: "SHA256withRSA"
ECDSA используется для эллиптических ключей:
sigalg: "SHA256withECDSA"
Для более низкоуровневого контроля CSR можно собрать вручную через
PKCS10:
const csr = new KJUR.asn1.csr.PKCS10({
subject: { str: "/CN=example.com" },
sbjpubkey: publicKey,
sigalg: "SHA256withRSA",
sbjprvkey: privateKey
});
csr.sign();
const pem = csr.getPEM();
Метод sign() выполняет криптографическую операцию:
Jsrsasign позволяет проверить корректность CSR:
const isValid = KJUR.asn1.csr.CSRUtil.verifyCSRPEM(csrPem);
Логика проверки:
В современных TLS-сценариях CN недостаточно, поэтому используется расширение SAN.
const csrPem = KJUR.asn1.csr.CSRUtil.newCSRPEM({
subject: {
str: "/CN=example.com"
},
extensions: [
{
extname: "subjectAltName",
array: [
{ dns: "example.com" },
{ dns: "www.example.com" },
{ ip: "192.168.1.1" }
]
}
],
sbjpubkey: publicKey,
sbjprvkey: privateKey,
sigalg: "SHA256withRSA"
});
SAN является критическим расширением, так как большинство CA игнорируют CN при проверке домена.
CSR можно декодировать для проверки структуры:
const info = KJUR.asn1.csr.CSRUtil.getInfo(csrPem);
console.log(info);
Результат включает:
Подпись CSR в Jsrsasign происходит в несколько этапов:
CertificationRequestInfoДля RSA используется схема PKCS#1 v1.5 или PSS (в зависимости от конфигурации).
Jsrsasign полностью работает с PEM-строками:
-----BEGIN CERTIFICATE REQUEST-----
...
-----END CERTIFICATE REQUEST-----
Конвертация:
const pem = csr.getPEM();
const parsed = KJUR.asn1.csr.CSRUtil.getInfo(pem);
1. Несоответствие ключей
Ошибка возникает, если публичный и приватный ключ не образуют пару.
2. Неподдерживаемый алгоритм
Некорректный sigalg приводит к исключению при
подписании.
3. Повреждённый PEM
Любое изменение строки CSR делает подпись недействительной.
4. Отсутствие SAN
Некоторые CA отклоняют CSR без расширения SAN даже при корректной подписи.
Jsrsasign по сути повторяет поведение OpenSSL:
OpenSSL:
openssl req -new -key private.key -out request.csr
Jsrsasign:
CSRUtil.newCSRPEM({...})
Разница заключается в том, что Jsrsasign позволяет формировать CSR полностью в JavaScript без внешних бинарных зависимостей.
ECDSA CSR требует правильного формата ключа:
const kp = KEYUTIL.generateKeypair("EC", "secp256r1");
const csrPem = KJUR.asn1.csr.CSRUtil.newCSRPEM({
subject: { str: "/CN=example.com" },
sbjpubkey: kp.pubKeyObj,
sbjprvkey: kp.prvKeyObj,
sigalg: "SHA256withECDSA"
});
ECDSA обеспечивает меньший размер ключа при сопоставимом уровне безопасности RSA 3072+.
Сформированный CSR используется в сценариях:
Jsrsasign позволяет формировать CSR прямо в браузере или Node.js без обращения к OpenSSL.
После подписания CSR и выпуска сертификата CA возвращает X.509 сертификат, который должен соответствовать:
Несоответствие любого параметра делает сертификат недействительным для клиента TLS.