В основе любой системы цифровых сертификатов лежит иерархическая модель доверия. Она позволяет масштабировать проверку подлинности, делегировать полномочия и минимизировать риски компрометации. В этой модели участвуют три ключевых типа сертификатов:
Библиотека jsrsasign предоставляет инструменты для генерации, подписи и проверки всех этих типов сертификатов, включая построение цепочек доверия.
Корневой сертификат — это верхний уровень иерархии. Он самоподписан и выступает в роли якоря доверия.
issuer === subject)const rs = require('jsrsasign');
// Генерация ключевой пары
const kp = rs.KEYUTIL.generateKeypair("RSA", 2048);
// Параметры сертификата
const cert = new rs.KJUR.asn1.x509.Certificate({
version: 3,
serial: { int: 1 },
sigalg: "SHA256withRSA",
issuer: { str: "/C=US/O=MyRootCA/CN=RootCA" },
subject: { str: "/C=US/O=MyRootCA/CN=RootCA" },
notbefore: "20240101000000Z",
notafter: "20340101000000Z",
sbjpubkey: kp.pubKeyObj,
ext: [
{ extname: "basicConstraints", cA: true, critical: true },
{ extname: "keyUsage", critical: true, names: ["keyCertSign", "cRLSign"] }
],
cakey: kp.prvKeyObj
});
// Подписание
cert.sign();
// PEM-представление
const rootCertPEM = cert.getPEM();
basicConstraints обязательно содержит
cA: truekeyUsage включает keyCertSignПромежуточный центр сертификации используется для разграничения ответственности и защиты Root CA. Root CA подписывает Intermediate CA, а тот уже выпускает конечные сертификаты.
// Генерация ключей
const intKP = rs.KEYUTIL.generateKeypair("RSA", 2048);
// Создание сертификата
const intCert = new rs.KJUR.asn1.x509.Certificate({
version: 3,
serial: { int: 2 },
sigalg: "SHA256withRSA",
issuer: { str: "/C=US/O=MyRootCA/CN=RootCA" },
subject: { str: "/C=US/O=MyIntermediateCA/CN=IntermediateCA" },
notbefore: "20240101000000Z",
notafter: "20300101000000Z",
sbjpubkey: intKP.pubKeyObj,
ext: [
{ extname: "basicConstraints", cA: true, critical: true, pathLen: 0 },
{ extname: "keyUsage", critical: true, names: ["keyCertSign", "cRLSign"] }
],
cakey: kp.prvKeyObj // ключ Root CA
});
intCert.sign();
const intCertPEM = intCert.getPEM();
issuer указывает на Root CApathLen ограничивает глубину цепочкиКонечный сертификат используется для идентификации серверов, пользователей или устройств. Он не может подписывать другие сертификаты.
cA: false// Генерация ключей
const eeKP = rs.KEYUTIL.generateKeypair("RSA", 2048);
// Создание сертификата
const eeCert = new rs.KJUR.asn1.x509.Certificate({
version: 3,
serial: { int: 3 },
sigalg: "SHA256withRSA",
issuer: { str: "/C=US/O=MyIntermediateCA/CN=IntermediateCA" },
subject: { str: "/C=US/O=MySite/CN=example.com" },
notbefore: "20240101000000Z",
notafter: "20250101000000Z",
sbjpubkey: eeKP.pubKeyObj,
ext: [
{ extname: "basicConstraints", cA: false },
{ extname: "keyUsage", critical: true, names: ["digitalSignature", "keyEncipherment"] },
{ extname: "subjectAltName", array: [{ dns: "example.com" }] }
],
cakey: intKP.prvKeyObj // ключ Intermediate CA
});
eeCert.sign();
const eeCertPEM = eeCert.getPEM();
Цепочка представляет собой последовательность:
End-Entity → Intermediate CA → Root CA
Каждый сертификат подписан предыдущим уровнем:
const x509 = new rs.X509();
// Загрузка сертификатов
x509.readCertPEM(eeCertPEM);
const eePubKey = x509.getPublicKey();
const intX509 = new rs.X509();
intX509.readCertPEM(intCertPEM);
const rootX509 = new rs.X509();
rootX509.readCertPEM(rootCertPEM);
// Проверка подписей
const isEEValid = x509.verifySignature(intX509.getPublicKey());
const isIntValid = intX509.verifySignature(rootX509.getPublicKey());
console.log(isEEValid && isIntValid);
cA: truecA: falseОграничивает допустимые операции:
keyCertSign,
cRLSigndigitalSignature,
keyEnciphermentИспользуется в TLS для указания доменных имён.
Для передачи клиенту часто объединяют сертификаты:
-----BEGIN CERTIFICATE-----
End-Entity
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
Intermediate
-----END CERTIFICATE-----
Root CA обычно не включается, так как уже находится в доверенном хранилище.
End-Entity может сначала создать CSR:
const csr = new rs.KJUR.asn1.csr.CertificationRequest({
subject: { str: "/C=US/O=MySite/CN=example.com" },
sbjpubkey: eeKP.pubKeyObj,
sigalg: "SHA256withRSA",
sbjprvkey: eeKP.prvKeyObj
});
const csrPEM = csr.getPEM();
Intermediate CA затем подписывает CSR и выпускает сертификат.
В реальной инфраструктуре используются:
jsrsasign поддерживает работу с CRL, но не реализует полноценный OCSP-клиент.
Такая архитектура обеспечивает баланс между безопасностью и масштабируемостью, а jsrsasign даёт полный контроль над созданием и управлением этой иерархией на уровне JavaScript.