Класс KJUR.asn1.DERSet

DERSet представляет собой реализацию ASN.1-типа SET, закодированного по правилам DER (Distinguished Encoding Rules). В контексте криптографической библиотеки Jsrsasign этот класс используется для формирования структур, где требуется неупорядоченное множество ASN.1-элементов с обязательной детерминированной сериализацией.

ASN.1 SET в логическом смысле допускает отсутствие порядка элементов. Однако DER накладывает строгое правило: все элементы SET должны быть отсортированы по их DER-байтовому представлению. Именно это поведение и реализует KJUR.asn1.DERSet — при создании объекта элементы автоматически приводятся к каноническому порядку перед кодированием.


SET в ASN.1 используется для хранения коллекции однотипных или разнотипных структур без фиксированного порядка. В отличие от SEQUENCE, где порядок элементов имеет смысл, SET определяется как математическое множество.

В DER (Distinguished Encoding Rules) ситуация меняется:

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

В Jsrsasign этот механизм инкапсулирован в KJUR.asn1.DERSet.


Общая структура KJUR.asn1.DERSet

Класс принадлежит пространству имён:

KJUR.asn1.DERSet

Он наследуется от базового ASN.1-узла библиотеки и использует общую инфраструктуру кодирования DER.

Основная задача — принять набор ASN.1-объектов и сформировать корректную DER-структуру SET.


Конструктор и параметры

Типичная сигнатура создания:

new KJUR.asn1.DERSet(params)

где params — объект конфигурации.

Основные поля:

  • array — массив ASN.1-объектов (DERInteger, DERUTF8String, DERSequence и т.д.)
  • дополнительные параметры могут передаваться через общую систему ASN.1-конфигурации Jsrsasign

Пример:

var set = new KJUR.asn1.DERSet({
  array: [
    new KJUR.asn1.DERUTF8String({str: "A"}),
    new KJUR.asn1.DERUTF8String({str: "B"})
  ]
});

Поведение сортировки элементов

Ключевая особенность DERSet заключается в том, что порядок элементов в исходном массиве не гарантируется в итоговом кодировании.

Перед сериализацией выполняется:

  1. кодирование каждого элемента в DER
  2. получение байтового представления
  3. сортировка по лексикографическому порядку байтов
  4. формирование итогового SET

Это критически важно для криптографических структур, где любое расхождение в байтах приводит к различию хэшей и подписи.


Отличие DERSet от DERSequence

Несмотря на схожую структуру, DERSet и DERSequence имеют принципиальные различия.

DERSequence

  • порядок элементов фиксирован и значим
  • используется в структурах сертификатов, подписей, алгоритмических описаний

DERSet

  • порядок логически не важен
  • порядок в кодировании строго определяется DER-правилами сортировки

Пример использования в криптографических структурах

DERSet часто встречается в расширениях сертификатов X.509, например:

  • набор альтернативных имён (SubjectAltName)
  • атрибуты сертификата
  • структуры CMS/PKCS#7

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

var attrSet = new KJUR.asn1.DERSet({
  array: [
    new KJUR.asn1.DERUTF8String({str: "role:admin"}),
    new KJUR.asn1.DERUTF8String({str: "department:IT"})
  ]
});

Такой объект может быть включён в более сложные ASN.1-конструкции, например в DERSequence.


Вложенность и комбинирование с другими ASN.1-типами

DERSet не является изолированным элементом. Он активно комбинируется с другими классами Jsrsasign:

  • DERSequence — для структурирования
  • DERInteger — числовые значения
  • DERBitString — битовые флаги
  • DEROctetString — бинарные данные
  • DERObjectIdentifier — идентификаторы алгоритмов

Пример вложенной структуры:

var complex = new KJUR.asn1.DERSequence({
  array: [
    new KJUR.asn1.DERInteger({int: 1}),
    new KJUR.asn1.DERSet({
      array: [
        new KJUR.asn1.DERUTF8String({str: "value1"}),
        new KJUR.asn1.DERUTF8String({str: "value2"})
      ]
    })
  ]
});

Кодирование в HEX и DER-представление

Любой объект DERSet может быть преобразован в DER-hex строку:

var hex = set.getEncodedHex();

Результат:

  • представляет бинарные данные в hex-форме
  • может использоваться в сертификатах, подписях и ASN.1-контейнерах
  • полностью соответствует DER-стандарту

Внутренние принципы работы

Внутри Jsrsasign DERSet опирается на базовую ASN.1-архитектуру:

  • каждый элемент реализует метод кодирования
  • DERSet агрегирует результаты
  • выполняет сортировку на уровне байтового массива
  • формирует окончательный TLV (Tag-Length-Value)

Сортировка — ключевой этап, обеспечивающий детерминированность результата.


Особенности при работе с пустым SET

Если массив array не задан или пуст:

  • формируется корректный DER SET без содержимого
  • длина структуры равна нулю
  • сохраняется валидность ASN.1
var emptySet = new KJUR.asn1.DERSet({});

Практическое значение в криптографии

DERSet критически важен в сценариях, где требуется:

  • воспроизводимость цифровых подписей
  • совместимость между разными реализациями ASN.1
  • корректная работа X.509 инфраструктуры
  • формирование PKCS#7 / CMS сообщений

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


Работа с уже закодированными элементами

DERSet допускает вложение уже готовых ASN.1-объектов. Каждый элемент должен быть экземпляром класса Jsrsasign ASN.1:

  • DERUTF8String
  • DERInteger
  • DERSequence
  • DERSet
  • и другие

Неподдерживаемые типы приводят к ошибкам кодирования или некорректному DER-выводу.


Взаимодействие с X.509 и PKI

В инфраструктуре открытых ключей DERSet используется при:

  • кодировании атрибутов сертификата
  • описании расширений X.509
  • формировании подписанных атрибутов CMS

Например, в структуре SignedAttributes PKCS#7 часто применяется SET OF атрибутов, реализуемый через DERSet.


Поведение при вложенной сортировке

Если элементы SET сами содержат SET или SEQUENCE:

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

Это обеспечивает строгую каноничность всей ASN.1-структуры независимо от глубины вложенности.