Разбор DN: страна, организация, CN и другие поля

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

DN состоит из набора атрибутов (Relative Distinguished Names, RDN), каждый из которых представляет собой пару «тип = значение». Порядок и структура имеют значение, поскольку DN кодируется и сравнивается как последовательность компонентов.

На практике DN может выглядеть так:

C=RU, ST=Moscow, L=Moscow, O=Example Ltd, OU=IT Department, CN=example.com, emailAddress=admin@example.com

Каждое поле несет конкретную семантику и используется в проверке сертификатов, построении цепочек доверия и идентификации субъектов.


Основные поля DN и их назначение

C — Country (страна)

Поле C обозначает страну в формате ISO 3166-1 alpha-2. Это один из самых формализованных компонентов DN.

Примеры:

  • C=RU
  • C=US
  • C=DE

В Jsrsasign это поле хранится как часть структуры X.500 имени и участвует в строгом сравнении DN.


ST — State or Province (регион)

Поле ST описывает регион или административную область.

Примеры:

  • ST=Moscow
  • ST=California
  • ST=Bavaria

Это поле не является обязательным, но часто используется в корпоративных сертификатах.


L — Locality (город)

Поле L указывает город или населённый пункт.

Примеры:

  • L=Saint Petersburg
  • L=New York

В отличие от ST, значение L обычно более локализовано.


O — Organization (организация)

Поле O представляет юридическое лицо или организацию.

Примеры:

  • O=Google LLC
  • O=Example Bank
  • O=Open Source Initiative

В контексте сертификатов это одно из ключевых идентификационных полей.


OU — Organizational Unit (подразделение)

Поле OU уточняет структуру внутри организации.

Примеры:

  • OU=IT Department
  • OU=Security Division
  • OU=DevOps

В корпоративных PKI системах может встречаться несколько OU в одном DN.


CN — Common Name (общее имя)

Поле CN является основным идентификатором субъекта.

Примеры:

  • CN=example.com
  • CN=John Doe
  • CN=VPN Gateway

Для TLS-сертификатов CN часто используется как доменное имя, хотя современные стандарты требуют проверки через SAN (Subject Alternative Name).


emailAddress — адрес электронной почты

Хотя формально не является частью строгого X.500 набора, поле emailAddress широко используется.

Примеры:

  • emailAddress=admin@example.com

В Jsrsasign оно обрабатывается как дополнительный атрибут DN.


Представление DN в ASN.1 и X.509

DN в сертификате X.509 кодируется через ASN.1 структуру Name, которая представляет собой последовательность RDNSequence.

Каждый RDN может содержать несколько атрибутов, объединённых логическим AND.

Пример ASN.1 структуры:

Name ::= CHOICE {
  rdnSequence RDNSequence
}

RDNSequence ::= SEQUENCE OF RelativeDistinguishedName

RelativeDistinguishedName ::= SET SIZE (1..MAX) OF AttributeTypeAndValue

Jsrsasign работает с этим представлением через внутренние ASN.1 классы, обеспечивая преобразование между строковым DN и бинарной DER-структурой.


Парсинг DN в Jsrsasign

В библиотеке Jsrsasign DN может быть представлен как строка или объект. Для разбора используется функциональность X.500 имени.

Пример создания объекта сертификата и извлечения DN:

const cert = new X509();
cert.readCertPEM(pemString);

const subject = cert.getSubject();
const issuer = cert.getIssuer();

Результат subject и issuer возвращается в строковом формате DN.


Разбор DN на компоненты

Jsrsasign предоставляет утилиты для разбора DN на структурированные элементы.

Пример:

const x500 = new KJUR.asn1.x509.X500Name({ str: dnString });

const attrs = x500.getArray();

Каждый элемент массива содержит объект:

{
  type: "CN",
  value: "example.com"
}

Таким образом можно получить доступ к отдельным компонентам DN без ручного парсинга строки.


Особенности парсинга строкового DN

DN в строковом виде имеет ряд особенностей:

  • разделитель компонентов: запятая ,
  • ключ и значение разделяются символом =
  • возможны экранированные запятые внутри значений
  • порядок компонентов сохраняется и может быть значим

Пример:

CN=example.com, O=Example\, Inc., C=RU

Здесь запятая внутри организации экранирована, иначе парсер воспринял бы её как разделитель RDN.


Нормализация DN

Jsrsasign выполняет нормализацию DN при сравнении:

  • игнорируются лишние пробелы
  • приводятся к единому регистру ключи атрибутов
  • экранированные символы интерпретируются корректно
  • порядок компонентов может учитываться в строгом режиме сравнения

Пример нормализации:

cn=example.com,o=Example,c=RU

и

C=RU, O=Example, CN=example.com

могут считаться эквивалентными в зависимости от режима сравнения.


Сравнение DN в Jsrsasign

Сравнение DN используется при проверке цепочек сертификатов.

Пример:

const isEqual = KJUR.asn1.x509.X500Name.compare(
  dn1,
  dn2,
  true
);

Флаг строгого сравнения учитывает порядок и точное соответствие структуры.

В нестрогом режиме сравниваются только пары ключ-значение.


Работа с многоуровневыми RDN

DN может содержать составные RDN, например:

OU=Security+CN=Subsystem, O=Example Corp, C=RU

Здесь один RDN содержит два атрибута. Jsrsasign корректно интерпретирует такие структуры как SET внутри RDNSequence.

При разборе такие элементы возвращаются как массив внутри одного уровня:

[
  [
    { type: "OU", value: "Security" },
    { type: "CN", value: "Subsystem" }
  ],
  ...
]

Кодирование DN в DER формат

При генерации сертификатов DN преобразуется в ASN.1 DER.

Пример создания имени:

const dn = new KJUR.asn1.x509.X500Name({
  str: "C=RU, O=Example, CN=example.com"
});

Далее DN включается в структуру сертификата:

const cert = new KJUR.asn1.x509.Certificate({
  subject: { str: dnString },
  issuer: { str: issuerDnString }
});

Jsrsasign автоматически строит ASN.1 дерево и сериализует его в DER.


Ошибки и неоднозначности DN

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

1. Неверное экранирование

O=Example, Inc.

воспринимается как два поля вместо одного.

Правильно:

O=Example\, Inc.

2. Дублирование атрибутов

CN=example.com, CN=other.com

Некоторые парсеры допускают это, но логика сравнения может быть неоднозначной.


3. Разный порядок компонентов

Хотя логически DN может быть равнозначным, в строгих реализациях порядок влияет на результат сравнения.


Практическое использование DN в проверке сертификатов

DN используется в следующих сценариях:

  • проверка совпадения субъекта и издателя
  • валидация цепочки доверия
  • фильтрация сертификатов по организации
  • идентификация клиента в TLS mutual authentication

Jsrsasign позволяет извлекать DN и сравнивать его на уровне компонентов, что особенно важно при построении кастомной PKI логики.


Извлечение отдельных полей DN

Пример получения конкретного поля:

const x500 = new KJUR.asn1.x509.X500Name({ str: dn });

const cn = x500.getField("CN");
const o  = x500.getField("O");
const c  = x500.getField("C");

Если поле отсутствует, возвращается null.


Работа DN в сертификатах TLS

В TLS-сертификатах DN используется совместно с расширением Subject Alternative Name. Несмотря на это, DN остаётся важным для:

  • идентификации в устаревших системах
  • корпоративных PKI
  • внутренней маршрутизации доверия

Jsrsasign позволяет анализировать DN без зависимости от браузерного API, что делает библиотеку удобной для серверной криптографии в JavaScript среде.