Класс KJUR.asn1.x509.TBSCertificate

KJUR.asn1.x509.TBSCertificate представляет собой реализацию структуры To Be Signed Certificate (TBSCertificate) из стандарта X.509, используемого в инфраструктуре публичных ключей (PKI). В библиотеке Jsrsasign этот класс отвечает за формирование ASN.1-представления «подписываемой части» сертификата до применения цифровой подписи.

TBSCertificate является центральным компонентом X.509 сертификата и включает всю основную информацию: субъект, издателя, срок действия, открытый ключ и дополнительные расширения. Именно этот объект впоследствии сериализуется в ASN.1 DER и подписывается приватным ключом удостоверяющего центра.


Структура TBSCertificate в X.509

Согласно RFC 5280, TBSCertificate имеет следующую логическую структуру:

  • version (версия сертификата)
  • serialNumber (серийный номер)
  • signature (алгоритм подписи)
  • issuer (издатель сертификата)
  • validity (срок действия)
  • subject (субъект сертификата)
  • subjectPublicKeyInfo (открытый ключ субъекта)
  • issuerUniqueID (опционально)
  • subjectUniqueID (опционально)
  • extensions (опционально)

В Jsrsasign эта структура моделируется через объектную модель ASN.1.


Конструктор класса

Класс создается с помощью:

new KJUR.asn1.x509.TBSCertificate(param)

Параметр param

Объект параметров может содержать следующие поля:

  • version — версия сертификата (0, 1, 2)
  • serial — серийный номер в HEX или BigInteger формате
  • sigalg — алгоритм подписи (например, “SHA256withRSA”)
  • issuer — Distinguished Name издателя
  • notbefore — начало действия сертификата
  • notafter — окончание действия сертификата
  • subject — Distinguished Name субъекта
  • sbjpubkey — открытый ключ субъекта
  • ext — массив или объект расширений X.509

Внутреннее представление DN (Distinguished Name)

Поля issuer и subject принимают структуру DN:

{
  str: "/C=RU/O=Example/CN=Test CA"
}

или расширенный формат:

{
  array: [
    { type: "C", value: "RU" },
    { type: "O", value: "Example" },
    { type: "CN", value: "Test CA" }
  ]
}

Внутри Jsrsasign DN преобразуется в ASN.1 структуру RDNSequence.


Работа с версией сертификата

Поле version кодируется следующим образом:

  • 0 → X.509 v1
  • 1 → X.509 v2
  • 2 → X.509 v3

ASN.1 представление:

version [0] EXPLICIT Version DEFAULT v1
Version ::= INTEGER { v1(0), v2(1), v3(2) }

В TBSCertificate версия кодируется как контекстно-специфичное поле:

version: 2

Серийный номер (serialNumber)

Серийный номер кодируется как INTEGER и должен быть уникальным в пределах издателя.

Пример:

serial: "01a3f4b9"

или:

serial: 123456789

Jsrsasign автоматически преобразует значение в DER INTEGER.


Алгоритм подписи (signature)

Поле signature указывает алгоритм, которым будет подписан сертификат:

  • SHA256withRSA
  • SHA384withECDSA
  • SHA512withRSA-PSS

Пример:

sigalg: "SHA256withRSA"

Важно, что TBSCertificate содержит только идентификатор алгоритма, сама подпись формируется после сериализации структуры.


Поле validity

Определяет временной интервал действия сертификата:

validity: {
  notBefore: "230101000000Z",
  notAfter:  "240101000000Z"
}

Формат соответствует ASN.1 UTCTime или GeneralizedTime.

Внутри Jsrsasign поддерживаются строки в формате:

  • YYMMDDHHMMSSZ
  • YYYYMMDDHHMMSSZ

Поле subjectPublicKeyInfo

Содержит публичный ключ субъекта и его алгоритм.

Пример RSA:

sbjpubkey: {
  alg: "RSA",
  n: "00c1d3...",
  e: "10001"
}

Пример ECDSA:

sbjpubkey: {
  alg: "EC",
  curve: "secp256r1",
  pub: "04a1b2c3..."
}

В ASN.1 это соответствует структуре:

SubjectPublicKeyInfo ::= SEQUENCE {
  algorithm AlgorithmIdentifier,
  subjectPublicKey BIT STRING
}

Расширения (extensions)

Поле ext используется для X.509 v3 расширений:

Пример:

ext: [
  {
    extname: "basicConstraints",
    cA: true,
    critical: true
  },
  {
    extname: "keyUsage",
    digitalSignature: true,
    keyCertSign: true
  }
]

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

  • basicConstraints
  • keyUsage
  • subjectAltName
  • authorityKeyIdentifier
  • subjectKeyIdentifier

Каждое расширение кодируется как ASN.1 SEQUENCE.


Генерация ASN.1 структуры

Основная задача TBSCertificate — преобразование параметров в ASN.1 объект:

var tbs = new KJUR.asn1.x509.TBSCertificate({
  version: 2,
  serial: "01",
  sigalg: "SHA256withRSA",
  issuer: { str: "/C=RU/O=CA/CN=Root CA" },
  notbefore: "240101000000Z",
  notafter: "250101000000Z",
  subject: { str: "/C=RU/O=Org/CN=User" },
  sbjpubkey: {
    alg: "RSA",
    n: "...",
    e: "10001"
  }
});

После создания объект может быть сериализован:

var asn1 = tbs.toASN1Object();
var der = asn1.getEncodedHex();

Метод toASN1Object

Ключевой метод класса:

TBSCertificate.prototype.toASN1Object = function()

Он возвращает ASN.1 структуру:

  • SEQUENCE TBSCertificate
  • с вложенными полями
  • с корректной DER-энкодировкой

Взаимодействие с X509 классом

TBSCertificate не используется изолированно. Он является частью полной цепочки:

  1. Формирование TBSCertificate
  2. Получение DER-представления
  3. Подпись приватным ключом
  4. Формирование X509Certificate

Пример интеграции:

var x = new KJUR.asn1.x509.Certificate({
  tbsobj: tbs,
  prvkey: privateKey
});

Особенности реализации в Jsrsasign

1. Абстракция ASN.1

TBSCertificate не формирует байты напрямую, а использует:

  • KJUR.asn1.DERSequence
  • KJUR.asn1.DERInteger
  • KJUR.asn1.DERBitString

2. Автоматическая нормализация DN

Строковые DN автоматически парсятся в RDNSequence.

3. Поддержка различных алгоритмов ключей

  • RSA
  • ECDSA
  • DSA (устаревший)

Ошибки и типичные проблемы

Некорректный формат времени

Неверный формат notBefore / notAfter приводит к ошибке ASN.1 кодирования.

Несоответствие алгоритма ключу

Если sigalg не соответствует типу ключа, сертификат становится невалидным.

Отсутствие обязательных полей

Минимально необходимы:

  • serial
  • issuer
  • subject
  • sbjpubkey
  • validity

Внутренняя роль TBSCertificate в PKI

TBSCertificate — это именно та часть сертификата, которая подписывается центром сертификации. Любое изменение хотя бы одного байта:

  • делает подпись недействительной
  • нарушает цепочку доверия
  • приводит к ошибке валидации

ASN.1 представление (упрощённо)

TBSCertificate ::= SEQUENCE {
  version          [0]  EXPLICIT INTEGER,
  serialNumber          INTEGER,
  signature             AlgorithmIdentifier,
  issuer                Name,
  validity              Validity,
  subject               Name,
  subjectPublicKeyInfo  SubjectPublicKeyInfo,
  extensions       [3]  EXPLICIT Extensions OPTIONAL
}