Построение CSR с помощью KJUR.asn1.csr

CSR (Certificate Signing Request) — это структурированный запрос на выпуск сертификата, который содержит информацию о субъекте, открытый ключ и дополнительные атрибуты. В контексте криптографии на JavaScript библиотека Jsrsasign предоставляет низкоуровневые инструменты для формирования CSR через модуль KJUR.asn1.csr, позволяя собирать PKCS

Структура CSR в формате PKCS#10

CSR формируется по стандарту PKCS#10 и включает несколько ключевых компонентов:

  • Subject — имя владельца сертификата (DN — Distinguished Name)
  • Public Key — открытый ключ, соответствующий приватному
  • Signature Algorithm — алгоритм подписи CSR
  • Attributes — дополнительные расширения (например, SAN)
  • Signature — цифровая подпись CSR

В Jsrsasign эти элементы собираются в объекте KJUR.asn1.csr.CSRUtil, а также через низкоуровневые ASN.1 структуры.

Подготовка ключевой пары

Перед созданием CSR требуется RSA или EC ключевая пара. В Jsrsasign генерация может выполняться так:

const kp = KEYUTIL.generateKeypair("RSA", 2048);

const privateKey = kp.prvKeyObj;
const publicKey = kp.pubKeyObj;

Ключевой момент: CSR всегда подписывается приватным ключом, а публичный включается в структуру запроса.

Формирование субъекта (Subject DN)

DN описывает владельца сертификата в формате X.500:

  • CN — Common Name
  • O — Organization
  • OU — Organizational Unit
  • C — Country
  • L — Locality
  • ST — State/Province

В Jsrsasign DN задаётся строкой:

const subject = "/C=KZ/O=Example Org/OU=IT Department/CN=example.com";

Важно соблюдать порядок и формат слэшей.

Использование KJUR.asn1.csr.CSRUtil

Основной инструмент для создания CSR — CSRUtil. Он позволяет собирать запрос на более высоком уровне:

const csrPem = KJUR.asn1.csr.CSRUtil.newCSRPEM({
    subject: {
        str: "/C=KZ/O=Example Org/OU=IT/CN=example.com"
    },
    sbjpubkey: publicKey,
    sigalg: "SHA256withRSA",
    sbjprvkey: privateKey
});

Разбор параметров

  • subject — DN в строковом формате
  • sbjpubkey — публичный ключ объекта Jsrsasign
  • sbjprvkey — приватный ключ для подписи CSR
  • sigalg — алгоритм подписи (например, SHA256withRSA)

Результатом является PEM-строка CSR:

-----BEGIN CERTIFICATE REQUEST-----
...
-----END CERTIFICATE REQUEST-----

Низкоуровневое построение CSR через KJUR.asn1

Для более гибкого контроля используется ручная сборка ASN.1 структуры.

CSR состоит из:

CertificationRequest ::= SEQUENCE {
    certificationRequestInfo CertificationRequestInfo,
    signatureAlgorithm AlgorithmIdentifier,
    signature BIT STRING
}

Пример ручного создания CSR

const csrInfo = new KJUR.asn1.csr.CertificationRequestInfo({
    subject: { str: "/C=KZ/O=Example/CN=example.com" },
    subjectPublicKey: publicKey
});

const algId = new KJUR.asn1.x509.AlgorithmIdentifier({
    name: "SHA256withRSA"
});

const csr = new KJUR.asn1.csr.CertificationRequest({
    certificationRequestInfo: csrInfo,
    signatureAlgorithm: algId,
    signature: privateKey.sign(csrInfo.getEncodedHex(), "sha256")
});

const pem = csr.getPEMString();

Этот подход используется, когда требуется:

  • нестандартная структура CSR
  • модификация ASN.1 полей
  • интеграция с внешними криптосервисами

Добавление расширений CSR (Subject Alternative Name)

Одним из наиболее важных расширений является SAN (Subject Alternative Name), позволяющий указывать дополнительные домены.

В Jsrsasign это делается через атрибуты CSR:

const san = {
    extname: "subjectAltName",
    array: [
        { dns: "example.com" },
        { dns: "www.example.com" },
        { ip: "192.168.0.1" }
    ]
};

const csrPem = KJUR.asn1.csr.CSRUtil.newCSRPEM({
    subject: {
        str: "/C=KZ/O=Example/CN=example.com"
    },
    sbjpubkey: publicKey,
    sbjprvkey: privateKey,
    extreq: [san],
    sigalg: "SHA256withRSA"
});

SAN расширения критичны для TLS-сертификатов современных веб-систем.

Кодирование и PEM-формат

Jsrsasign автоматически кодирует CSR в DER, затем в Base64 и оборачивает в PEM-структуру.

Если требуется получить DER:

const csr = KJUR.asn1.csr.CSRUtil.newCSR({
    subject: { str: "/C=KZ/CN=example.com" },
    sbjpubkey: publicKey,
    sbjprvkey: privateKey
});

const derHex = csr.getEncodedHex();

DER используется в низкоуровневых протоколах и при интеграции с аппаратными HSM.

Проверка CSR

Jsrsasign позволяет разобрать CSR и проверить его корректность:

const parsed = KJUR.asn1.csr.CSRUtil.getInfo(csrPem);

console.log(parsed.subject);
console.log(parsed.sbjpubkey);

Также возможно верифицировать подпись:

const isValid = KJUR.asn1.csr.CSRUtil.verify(csrPem);

Работа с разными алгоритмами подписи

Поддерживаются основные алгоритмы:

  • SHA1withRSA (устаревший)
  • SHA256withRSA
  • SHA384withRSA
  • SHA512withRSA
  • ECDSA варианты

Пример:

sigalg: "SHA384withRSA"

Выбор алгоритма напрямую влияет на совместимость с удостоверяющими центрами.

Использование EC ключей

CSR может быть создан не только на RSA, но и на эллиптических кривых:

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"
});

EC CSR обычно меньше по размеру и быстрее в вычислениях.

Частые ошибки при формировании CSR

Несоответствие ключей

Одна из критических ошибок — использование разных ключевых пар:

  • публичный ключ от одного генератора
  • приватный от другого

Это делает CSR недействительным.

Неправильный DN формат

Jsrsasign требует строгий формат /C=.../O=.../CN=.... Пробелы и отсутствие слэшей приводят к ошибкам.

Неверный алгоритм подписи

ECDSA ключи нельзя подписывать RSA алгоритмами и наоборот.

Интеграция CSR в процесс выпуска сертификатов

Сформированный CSR обычно отправляется в:

  • корпоративный CA
  • Let’s Encrypt (через ACME протокол)
  • внутренние PKI системы

Jsrsasign позволяет подготовить CSR полностью на клиентской стороне без серверной криптографии, что особенно важно для браузерных приложений и Node.js сервисов с ограниченными правами доступа к ключам.