Добавление собственных OID

В криптографических структурах, основанных на ASN.1, идентификаторы объектов (OID, Object Identifier) играют центральную роль: они однозначно обозначают алгоритмы, расширения сертификатов, атрибуты и множество других сущностей. В jsrsasign работа с OID встроена в модуль X.509, где используется внутренний реестр сопоставлений «имя ↔︎ OID». При необходимости расширения стандартного набора возникает задача добавления собственных OID и корректного их использования в генерации и разборе сертификатов.

В библиотеке jsrsasign существует централизованная таблица соответствий, используемая при обработке X.509 структур. Она хранится в пространстве имён:

KJUR.asn1.x509.OID

Внутри неё обычно присутствуют две ключевые структуры:

  • name2oid — сопоставление человекочитаемого имени с OID строкой
  • oid2name — обратное сопоставление OID со стандартным именем

Эти таблицы используются при:

  • генерации сертификатов (когда задаются расширения и атрибуты по имени)
  • парсинге сертификатов (для отображения понятных названий вместо числовых идентификаторов)

Пример стандартного элемента:

KJUR.asn1.x509.OID.name2oid["serverAuth"] === "1.3.6.1.5.5.7.3.1"

Принцип добавления собственного OID

Добавление собственного идентификатора в jsrsasign не требует модификации самой библиотеки — достаточно расширить внутренние таблицы.

Ключевой принцип: OID должен быть зарегистрирован в обеих направлениях, иначе возможны несогласованности при кодировании и декодировании.

Определение собственного OID

Сначала выбирается уникальный идентификатор, например:

const MY_CUSTOM_OID = "1.2.3.4.5.6.7.8.1";

Важно, чтобы пространство OID не пересекалось с публичными регистрами, если используется в реальных PKI-системах.

Регистрация имени

Далее добавляется логическое имя, которое будет использоваться в коде:

KJUR.asn1.x509.OID.name2oid["myCustomExtension"] = MY_CUSTOM_OID;
KJUR.asn1.x509.OID.oid2name[MY_CUSTOM_OID] = "myCustomExtension";

После этого библиотека начинает воспринимать строку "myCustomExtension" как валидный идентификатор.

Использование в X.509 расширениях

Чаще всего собственные OID применяются в контексте расширений сертификатов. В jsrsasign расширения формируются через структуру ext при создании сертификата.

Пример добавления пользовательского расширения:

var ext = [
  {
    extname: "1.2.3.4.5.6.7.8.1",
    extn: "546573742076616c7565" // HEX-encoded value
  }
];

Однако более читаемый вариант достигается после регистрации имени:

var ext = [
  {
    extname: "myCustomExtension",
    extn: "546573742076616c7565"
  }
];

В этом случае jsrsasign автоматически подставит соответствующий OID из реестра.

Работа с ASN.1 представлением

OID в ASN.1 кодируется как OBJECT IDENTIFIER. jsrsasign внутри использует ASN.1 DER-кодирование, и добавленные OID проходят стандартную сериализацию.

При ручной работе через ASN.1 утилиты:

var asn1oid = new KJUR.asn1.DERObjectIdentifier({ oid: MY_CUSTOM_OID });

или через строковое имя после регистрации:

var asn1oid = new KJUR.asn1.DERObjectIdentifier({ oid: "myCustomExtension" });

Во втором случае происходит резолв через name2oid.

Поведение при разборе сертификатов

Если сертификат содержит неизвестный OID, jsrsasign обычно возвращает его в «сыром» виде:

1.2.3.4.5.6.7.8.1

После регистрации обратного отображения:

KJUR.asn1.x509.OID.oid2name["1.2.3.4.5.6.7.8.1"] = "myCustomExtension";

разбор начинает выдавать человекочитаемое имя.

Это особенно важно при:

  • отладке корпоративных PKI
  • работе с нестандартными расширениями
  • интеграции с HSM и приватными удостоверяющими центрами

Динамическое расширение реестра

Регистрация может выполняться в любой момент выполнения программы, до создания или анализа сертификатов.

Типичный шаблон инициализации:

(function registerCustomOIDs() {
  const OID = KJUR.asn1.x509.OID;

  OID.name2oid["myCustomExtension"] = "1.2.3.4.5.6.7.8.1";
  OID.oid2name["1.2.3.4.5.6.7.8.1"] = "myCustomExtension";

  OID.name2oid["internalPolicy"] = "1.2.3.4.5.6.7.8.2";
  OID.oid2name["1.2.3.4.5.6.7.8.2"] = "internalPolicy";
})();

Такой подход обеспечивает централизованную регистрацию всех корпоративных расширений.

Особенности совместимости

При расширении OID-реестра важно учитывать несколько особенностей внутренней логики jsrsasign:

  • строковое имя имеет приоритет только при наличии записи в name2oid
  • при конфликте имён последнее присваивание перезаписывает предыдущее значение
  • отсутствие обратного маппинга не ломает кодирование, но ухудшает декодирование
  • OID всегда сериализуется как строка, даже если задаётся через имя

Использование в сложных структурах сертификатов

В расширенных сценариях OID используется не только в extensions, но и в атрибутах:

  • Subject Alternative Name
  • Certificate Policies
  • Custom Authentication Attributes
  • Private Extensions

Пример политики сертификата:

var certPolicy = {
  extname: "certificatePolicies",
  array: [
    {
      policyoid: "myCustomExtension"
    }
  ]
};

После регистрации OID это становится эквивалентно:

1.2.3.4.5.6.7.8.1

Контроль и отладка реестра OID

При работе с расширениями часто требуется проверить текущее состояние реестра:

console.log(KJUR.asn1.x509.OID.name2oid);
console.log(KJUR.asn1.x509.OID.oid2name);

Это позволяет:

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

Паттерны организации пользовательских OID

В крупных системах обычно используется структурированная схема:

1.2.643.<company_id>.<module>.<feature>

или

1.3.6.1.4.1.<enterprise_number>.<internal_tree>

jsrsasign не накладывает ограничений на структуру, но корректная иерархия облегчает сопровождение и совместимость с PKI-инфраструктурой.

Влияние на генерацию и проверку сертификатов

После добавления собственного OID он становится частью криптографического конверта сертификата. Это означает:

  • он участвует в подписи
  • влияет на валидацию цепочки
  • сохраняется в DER-представлении
  • может проверяться сторонними библиотеками

Поэтому любые изменения реестра должны быть синхронизированы между всеми участниками системы, использующими одинаковые сертификаты.

Сопоставление с внешними системами

При интеграции с OpenSSL или Java PKI важно учитывать, что jsrsasign использует строковое представление OID без преобразований. Это обеспечивает совместимость, если OID определён одинаково во всех системах.

Пример сопоставления:

Система Представление OID
jsrsasign “1.2.3.4.5.6.7.8.1”
OpenSSL OBJECT IDENTIFIER
Java X509 ASN.1 ObjectIdentifier

Обработка ошибок при отсутствии регистрации

Если используется имя, отсутствующее в name2oid, библиотека не сможет преобразовать его в OID и возможны ошибки при генерации структуры.

Типичный сценарий:

  • вход: "unknownExtension"
  • результат: undefined вместо OID
  • следствие: некорректный ASN.1 объект

Поэтому регистрация должна происходить до построения любых криптографических структур.

Расширение через модульную инициализацию

В архитектурно сложных приложениях часто выделяют отдельный модуль:

export function initOIDs() {
  const OID = KJUR.asn1.x509.OID;

  OID.name2oid["auditLog"] = "1.2.3.4.5.6.7.8.10";
  OID.oid2name["1.2.3.4.5.6.7.8.10"] = "auditLog";
}

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