Формирование DN через KJUR.asn1.x509.X500Name

Distinguished Name (DN) в инфраструктуре X.509 представляет собой структурированную строку, идентифицирующую субъекта или издателя сертификата. В рамках криптографических операций DN используется для однозначного описания сущности: пользователя, сервера, организации или устройства.

В формате X.509 DN состоит из набора атрибутов, представленных в виде пар ключ–значение. Эти атрибуты формируют иерархическую структуру, которая затем кодируется в ASN.1 DER при создании сертификатов. Библиотека Jsrsasign предоставляет высокоуровневый механизм для формирования таких структур через KJUR.asn1.x509.X500Name.


DN в контексте X.509 обычно включает следующие элементы:

  • C — Country (страна)
  • ST — State or Province (регион)
  • L — Locality (город)
  • O — Organization (организация)
  • OU — Organizational Unit (подразделение)
  • CN — Common Name (общее имя)
  • Email — электронная почта (реже используется в сертификатах X.509v3)

Каждый из этих компонентов является атрибутом RDN (Relative Distinguished Name). Несколько RDN объединяются в последовательность, образуя DN.

В ASN.1 представлении DN кодируется как:

  • Name ::= RDNSequence
  • RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
  • RelativeDistinguishedName ::= SET OF AttributeTypeAndValue

KJUR.asn1.x509.X500Name как инструмент формирования DN

В Jsrsasign класс KJUR.asn1.x509.X500Name предназначен для создания ASN.1 структуры имени X.500, которая используется при генерации сертификатов, CSR и других криптографических объектов.

Объект принимает на вход описание DN в виде объекта JavaScript или строки и преобразует его в ASN.1 структуру.


Формирование DN через объектную нотацию

Наиболее распространённый способ задания DN — использование JavaScript-объекта:

var dn = new KJUR.asn1.x509.X500Name({
  C: "RU",
  ST: "Moscow",
  L: "Moscow",
  O: "Example Company",
  OU: "IT Department",
  CN: "example.com",
  emailAddress: "admin@example.com"
});

Каждое свойство объекта соответствует одному атрибуту DN. Порядок свойств в объекте не всегда критичен, поскольку внутри ASN.1 структура упорядочивается согласно правилам X.500.


Использование строкового представления DN

Jsrsasign также поддерживает строковый формат:

var dn = new KJUR.asn1.x509.X500Name(
  "C=RU, ST=Moscow, L=Moscow, O=Example Company, OU=IT Department, CN=example.com"
);

При таком способе библиотека выполняет парсинг строки и преобразует её в внутреннюю ASN.1 структуру.

Особенности строкового формата:

  • Атрибуты разделяются запятыми
  • Допускаются пробелы вокруг разделителей
  • Поддерживаются стандартные OID-алиасы (C, ST, L, O, OU, CN)

Внутренняя модель ASN.1 в X500Name

При создании объекта X500Name происходит преобразование входных данных в последовательность ASN.1 объектов:

  • KJUR.asn1.DERSet — представляет RDN
  • KJUR.asn1.DERSequence — объединяет RDNSequence
  • KJUR.asn1.DERUTF8String или DERPrintableString — кодирует значения атрибутов

Пример логической структуры:

SEQUENCE
 ├── SET
 │    ├── AttributeTypeAndValue (C=RU)
 ├── SET
 │    ├── AttributeTypeAndValue (ST=Moscow)
 ├── SET
 │    ├── AttributeTypeAndValue (O=Example Company)

Особенности кодирования атрибутов

Jsrsasign автоматически выбирает тип кодирования значений:

  • PrintableString — для простых ASCII-значений
  • UTF8String — для Unicode-строк
  • IA5String — для email и доменных имён

Это важно при генерации сертификатов, поскольку несоответствие типов может привести к несовместимости с некоторыми TLS-реализациями.


Пример использования в генерации CSR

DN, созданный через X500Name, часто используется в объекте CSR:

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

var csr = new KJUR.asn1.csr.CSR({
  subject: {
    str: "C=RU, O=Example Company, CN=example.com"
  },
  sbjpubkey: kp.pubKeyObj,
  sigalg: "SHA256withRSA",
  sbjprvkey: kp.prvKeyObj
});

var pem = csr.getPEM();

В этом случае DN формируется как часть поля subject.


Альтернативное создание через X500Name

При более явном контроле можно передать объект X500Name напрямую:

var subjectName = new KJUR.asn1.x509.X500Name({
  C: "RU",
  O: "Example Company",
  CN: "example.com"
});

var csr = new KJUR.asn1.csr.CSR({
  subject: subjectName,
  sbjpubkey: kp.pubKeyObj,
  sigalg: "SHA256withRSA",
  sbjprvkey: kp.prvKeyObj
});

Такой подход позволяет избежать промежуточного строкового представления и уменьшает риск ошибок парсинга.


Поддерживаемые атрибуты DN

Помимо базовых полей, X500Name поддерживает расширенный набор атрибутов:

  • DC — Domain Component
  • serialNumber — серийный номер субъекта
  • postalCode — почтовый индекс
  • street — улица
  • title — должность
  • businessCategory — категория бизнеса

Пример расширенного DN:

var dn = new KJUR.asn1.x509.X500Name({
  C: "US",
  ST: "California",
  L: "San Francisco",
  O: "Tech Corp",
  OU: "Security Division",
  CN: "api.techcorp.com",
  DC: "techcorp",
  DC: "com",
  serialNumber: "123456789"
});

Особенности работы с порядком RDN

Хотя в JavaScript-объекте порядок свойств может казаться нестрогим, в DN последовательность RDN имеет значение.

В ASN.1:

  • первый элемент обычно считается наиболее специфичным
  • последний — наиболее общим

Jsrsasign при сериализации может нормализовать порядок в соответствии с внутренними правилами X.500.


Экспорт ASN.1 структуры

Объект X500Name может быть преобразован в ASN.1 DER:

var asn1 = dn.getASN1Object();
var hex = asn1.getEncodedHex();

Этот HEX-представление используется при формировании сертификатов X.509.


Типичные ошибки при формировании DN

При работе с X500Name часто возникают следующие проблемы:

  • Использование неподдерживаемых атрибутов без корректного OID
  • Некорректное экранирование запятых в строковом формате
  • Несоответствие UTF-8 кодировки для международных символов
  • Дублирование DC без понимания иерархии домена

Пример ошибки:

"C=RU, O=Example, CN=John, Doe"

Запятая в CN без экранирования приведёт к неправильному разбору.

Корректный вариант:

"C=RU, O=Example, CN=\"John, Doe\""

Взаимодействие с сертификатами X.509

DN, сформированный через X500Name, используется в:

  • Subject сертификата
  • Issuer сертификата
  • CSR (Certificate Signing Request)

В случае самоподписанных сертификатов Subject и Issuer часто совпадают:

var cert = new KJUR.asn1.x509.Certificate({
  subject: dn,
  issuer: dn,
  pubkey: kp.pubKeyObj,
  sigalg: "SHA256withRSA",
  sbjprvkey: kp.prvKeyObj
});

Нормализация и совместимость

Разные реализации X.509 могут по-разному интерпретировать DN:

  • OpenSSL допускает вариативный порядок атрибутов
  • Java KeyStore может требовать строгого соответствия
  • браузерные TLS-стэки чувствительны к encoding type

Jsrsasign решает часть этих проблем за счёт унифицированного ASN.1 слоя, но конечная совместимость зависит от конечного потребителя сертификата.


Поведение при сериализации в PEM

После формирования DN он становится частью DER-структуры сертификата, которая затем кодируется в PEM:

-----BEGIN CERTIFICATE-----
MIIC...
-----END CERTIFICATE-----

DN внутри этого блока уже представлен в бинарном ASN.1 виде и не подлежит изменению без пересборки сертификата.


Роль X500Name в общей архитектуре Jsrsasign

KJUR.asn1.x509.X500Name является связующим звеном между:

  • высокоуровневым JavaScript API
  • низкоуровневой ASN.1 структурой
  • криптографическими объектами (CSR, сертификаты, CRL)

Он обеспечивает единообразное представление идентичности субъекта в рамках всей библиотеки, исключая необходимость ручного построения ASN.1 деревьев.