Модуль asn1

ASN.1 (Abstract Syntax Notation One) в контексте криптографической библиотеки Jsrsasign используется как фундаментальный слой для построения и разбора структур, применяемых в сертификатах X.509, ключах PKCS, подписях CMS и других форматах, основанных на DER/BER кодировании. Модуль реализует создание ASN.1 объектов, их вложенность и сериализацию в бинарный формат, совместимый с криптографическими стандартами.


В Jsrsasign ASN.1 реализован через пространство имён KJUR.asn1, где каждая сущность представляет собой узел дерева ASN.1. Любая структура строится как иерархия объектов, где базовый класс определяет общий интерфейс кодирования.

Ключевая концепция — представление ASN.1 дерева как композиции:

  • примитивных типов (INTEGER, OCTET STRING, OBJECT IDENTIFIER)
  • конструктивных типов (SEQUENCE, SET)
  • специализированных контейнеров (BIT STRING, ANY)

Каждый объект способен сериализоваться в DER (Distinguished Encoding Rules), что критично для криптографической совместимости.


Базовый класс ASN.1 объектов

Все элементы наследуются от абстрактной модели:

  • KJUR.asn1.ASN1Object
  • или более специализированных классов через ASN1Util

Базовый объект определяет:

  • хранение тегов ASN.1
  • правила кодирования длины
  • механизм рекурсивного построения бинарного представления

Ключевая особенность — ленивое кодирование: объект может быть создан как структура, а сериализация происходит только при вызове метода получения HEX/DER представления.


SEQUENCE как основа структурирования

SEQUENCE — основной строительный блок ASN.1.

В Jsrsasign он представлен классом:

  • KJUR.asn1.DERSequence

Он используется для группировки полей:

  • сертификатов X.509
  • ключевых структур PKCS#1 / PKCS#8
  • подписанных данных

SEQUENCE хранит массив дочерних ASN.1 объектов и при сериализации кодирует их последовательно.

Особенность DER-формата: порядок элементов строго фиксирован и важен для криптографической проверки.


Примитивные типы данных

INTEGER

Представляется через:

  • KJUR.asn1.DERInteger

Используется для:

  • модулей RSA ключей
  • экспоненты
  • серийных номеров сертификатов

Особенности:

  • поддержка отрицательных и положительных чисел
  • автоматическая нормализация ведущих нулей
  • кодирование big-endian

OBJECT IDENTIFIER (OID)

Реализуется как:

  • KJUR.asn1.DERObjectIdentifier

OID используется для идентификации:

  • алгоритмов подписи (RSA, ECDSA, SHA-256)
  • атрибутов сертификатов
  • расширений X.509

Структура OID кодируется через базовую схему сжатия (base-128 encoding), где первые два числа объединяются в одно значение.


OCTET STRING

Класс:

  • KJUR.asn1.DEROctetString

Применение:

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

Особенность: может содержать как «сырые» байты, так и вложенные DER-структуры.


BIT STRING

Класс:

  • KJUR.asn1.DERBitString

Используется для:

  • публичных ключей
  • цифровых подписей
  • флагов сертификатов

Структура включает:

  • байт смещения битов (unused bits)
  • бинарный payload

Строковые типы

ASN.1 поддерживает различные строковые представления, которые в Jsrsasign реализованы отдельными классами:

  • DERUTF8String
  • DERPrintableString
  • DERIA5String

Они используются в:

  • subject/issuer DN сертификатов
  • email-адресах
  • идентификаторах организаций

Кодирование зависит от типа строки, включая ограничение допустимых символов (например, PrintableString имеет строгий набор ASCII символов).


UTCTime и GeneralizedTime

Классы:

  • KJUR.asn1.DERUTCTime
  • KJUR.asn1.DERGeneralizedTime

Используются для временных меток:

  • срок действия сертификата (notBefore / notAfter)
  • временные метки подписей

UTCTime применяет двухзначный год, GeneralizedTime — четырёхзначный.


Конструкторы и вспомогательные классы

Для удобства построения ASN.1 деревьев Jsrsasign предоставляет высокоуровневые конструкторы:

  • ASN1Util.newObject
  • KJUR.asn1.DERTaggedObject

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


DER кодирование

DER (Distinguished Encoding Rules) — строгая форма BER. В Jsrsasign реализация кодирования включает три этапа:

  1. Определение типа (tag)
  2. Вычисление длины
  3. Сериализация значения

Каждый объект предоставляет метод:

  • getEncodedHex()

который возвращает шестнадцатеричное представление DER.

Ключевая особенность DER в библиотеке — детерминированность результата: одинаковая структура всегда даёт одинаковый байтовый вывод.


Вложенные структуры

ASN.1 дерево в Jsrsasign строится рекурсивно. Пример типичной композиции:

  • SEQUENCE

    • SEQUENCE

      • INTEGER
      • OID
    • BIT STRING

Каждый узел может содержать другие узлы без ограничений глубины.

Это позволяет моделировать:

  • X.509 сертификаты
  • PKCS#8 ключи
  • CMS SignedData

Работа с X.509 структурами через ASN.1 слой

Хотя Jsrsasign предоставляет высокоуровневый API X509, внутри он полностью опирается на ASN.1 модуль.

Структура сертификата включает:

  • TBSCertificate (SEQUENCE)
  • AlgorithmIdentifier (SEQUENCE)
  • SignatureValue (BIT STRING)

ASN.1 модуль отвечает за:

  • построение TBSCertificate
  • кодирование issuer/subject
  • упаковку расширений

Tagged objects и контекстная типизация

ASN.1 поддерживает явные и неявные теги:

  • EXPLICIT
  • IMPLICIT

В Jsrsasign это реализовано через:

  • KJUR.asn1.DERTaggedObject

Он позволяет:

  • переопределять тип узла
  • сохранять совместимость с RFC-структурами
  • работать с расширениями протоколов

Кодирование длины

Механизм длины в DER:

  • короткая форма (1 байт) для значений < 128
  • длинная форма для больших структур

Jsrsasign автоматически выбирает формат, исходя из размера содержимого.


Пример построения структуры

var seq = new KJUR.asn1.DERSequence({
  array: [
    new KJUR.asn1.DERInteger({int: 123}),
    new KJUR.asn1.DERObjectIdentifier({oid: "1.2.840.113549.1.1.5"})
  ]
});

var hex = seq.getEncodedHex();

Здесь:

  • создаётся SEQUENCE
  • внутрь помещаются INTEGER и OID
  • результат кодируется в DER hex

Внутренние особенности реализации

ASN.1 слой Jsrsasign построен на следующих принципах:

  • минимизация зависимостей
  • чистая реализация DER без внешних библиотек
  • строгая совместимость с OpenSSL и Java Crypto API
  • предсказуемая сериализация

Объекты не используют глобальное состояние, что позволяет безопасно строить структуры параллельно.


Типовые сценарии использования слоя ASN.1

ASN.1 модуль используется как фундамент для:

  • генерации RSA/ECDSA ключей
  • создания CSR (Certificate Signing Request)
  • разбора сертификатов X.509
  • формирования CMS подписей
  • работы с PKCS#1 и PKCS#8 форматами

Каждый из этих сценариев сводится к построению ASN.1 дерева и его последующей сериализации.


Ограничения и особенности работы с DER

При работе с ASN.1 в Jsrsasign важно учитывать:

  • отсутствие поддержки BER-расширений (только DER)
  • строгую типизацию строк
  • чувствительность к порядку элементов SEQUENCE
  • обязательность корректного padding для BIT STRING

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