В X.509 сертификате ключевые идентификационные поля представлены через Distinguished Name (DN), которые описывают субъект (subject) и издателя (issuer). Эти структуры содержат набор атрибутов, таких как Common Name (CN), Organization (O), Organizational Unit (OU), Country (C) и другие.
В контексте JavaScript-библиотеки jsrsasign работа с этими полями
выполняется через объект X509, который предоставляет методы
для разбора PEM-сертификата и извлечения данных в удобном формате.
Перед получением subject и issuer сертификат необходимо загрузить и разобрать:
const certPEM = `
-----BEGIN CERTIFICATE-----
MIIC...
-----END CERTIFICATE-----
`;
const x509 = new X509();
x509.readCertPEM(certPEM);
После вызова readCertPEM объект сертификата становится
доступным для анализа.
Самый простой способ извлечения данных — использование строковых методов.
const subjectStr = x509.getSubjectString();
const issuerStr = x509.getIssuerString();
console.log(subjectStr);
console.log(issuerStr);
Результат обычно выглядит как DN-строка:
CN=example.com, O=Example Corp, C=US
CN=Let's Encrypt Authority X3, O=Let's Encrypt, C=US
Эти методы полезны для быстрого отображения информации без дополнительной обработки.
Для более глубокой работы используется метод, возвращающий структурированное представление DN.
const subject = x509.getSubject();
Результат представляет собой объект с массивом атрибутов:
{
array: [
{ type: "CN", value: "example.com" },
{ type: "O", value: "Example Corp" },
{ type: "C", value: "US" }
]
}
Такой формат удобен для программной обработки, фильтрации и поиска конкретных значений.
Обработка DN сводится к итерации по массиву:
const subject = x509.getSubject();
subject.array.forEach(attr => {
console.log(attr.type + " = " + attr.value);
});
Типы атрибутов соответствуют стандарту X.509:
Issuer извлекается аналогичным способом:
const issuer = x509.getIssuer();
Структура полностью идентична subject:
{
array: [
{ type: "CN", value: "R3" },
{ type: "O", value: "Let's Encrypt" },
{ type: "C", value: "US" }
]
}
Subject описывает владельца сертификата, тогда как issuer указывает центр сертификации, который его подписал.
Пример сопоставления:
const subject = x509.getSubject();
const issuer = x509.getIssuer();
const subjectCN = subject.array.find(x => x.type === "CN")?.value;
const issuerCN = issuer.array.find(x => x.type === "CN")?.value;
Такой подход позволяет анализировать цепочки доверия и проверять соответствие сертификатов.
Часто требуется получить конкретное поле без обхода массива:
function getDNValue(dn, type) {
const item = dn.array.find(x => x.type === type);
return item ? item.value : null;
}
const cn = getDNValue(x509.getSubject(), "CN");
const country = getDNValue(x509.getSubject(), "C");
Этот подход упрощает работу с сертификатами в прикладных сценариях, таких как проверка домена или региона.
DN может содержать повторяющиеся атрибуты:
{
array: [
{ type: "OU", value: "IT" },
{ type: "OU", value: "Security" }
]
}
Обработка всех значений выполняется без предположения уникальности:
const ous = x509.getSubject().array
.filter(x => x.type === "OU")
.map(x => x.value);
Для проверки идентичности сертификатов часто используется сопоставление DN:
function dnToString(dn) {
return dn.array
.map(x => `${x.type}=${x.value}`)
.join(", ");
}
const subjectA = dnToString(x509.getSubject());
const issuerA = dnToString(x509.getIssuer());
Такой подход позволяет сравнивать сертификаты на уровне строкового представления или по отдельным компонентам.
Библиотека jsrsasign использует ASN.1-парсинг для преобразования DER-структуры сертификата в JavaScript-объекты. Distinguished Name разбирается как последовательность Relative Distinguished Names (RDN), каждый из которых может содержать один или несколько атрибутов.
Это важно при работе с нестандартными сертификатами, где структура DN может отличаться по порядку или содержанию.
В прикладной разработке данные поля используются для:
Некоторые сертификаты могут не содержать всех атрибутов:
const subject = x509.getSubject();
const org = subject.array.find(x => x.type === "O");
const orgValue = org ? org.value : "unknown";
Корректная обработка отсутствующих значений критична при работе с разнородными сертификатами.
Для унификации данных часто выполняется нормализация:
function normalizeDN(dn) {
return dn.array.reduce((acc, x) => {
acc[x.type] = (acc[x.type] || []).concat(x.value);
return acc;
}, {});
}
const normalizedSubject = normalizeDN(x509.getSubject());
Результат:
{
CN: ["example.com"],
O: ["Example Corp"],
C: ["US"]
}
Проверка цепочки сертификатов может включать сравнение issuer одного сертификата с subject следующего:
const isChainValid = dnToString(certA.getIssuer()) === dnToString(certB.getSubject());
Такой метод применяется при ручной проверке доверенных цепочек без использования системных хранилищ сертификатов.