KJUR.asn1: базовые классы и методы

KJUR.asn1 представляет собой одну из ключевых частей библиотеки jsrsasign, реализующую работу с ASN.1 структурой данных. ASN.1 (Abstract Syntax Notation One) используется в криптографии для описания и кодирования сложных структур, таких как сертификаты X.509, ключи, подписи и другие элементы PKI.

Внутри jsrsasign пространство имён KJUR.asn1 построено как набор базовых классов, которые формируют иерархию объектов DER/BER кодирования. Основная идея заключается в том, что каждый ASN.1 элемент представлен отдельным классом с единым интерфейсом сериализации в бинарный формат.


Основой является абстрактный класс ASN1Object, от которого наследуются все остальные ASN.1 типы. Он задаёт общий контракт для объектов, которые могут быть закодированы в DER.

Ключевая ответственность ASN1Object:

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

Типичная цепочка наследования:

KJUR.asn1.ASN1Object
   ├── KJUR.asn1.DERAbstractString
   │       ├── DERUTF8String
   │       ├── DERPrintableString
   │       ├── DERIA5String
   │
   ├── DERInteger
   ├── DERBitString
   ├── DEROctetString
   ├── DERNull
   ├── DERObjectIdentifier
   ├── DERSequence
   ├── DERSet

ASN1Object: базовый класс

ASN1Object является фундаментом всей системы кодирования ASN.1.

Основные методы:

  • getEncodedHex() Возвращает DER-кодированное представление объекта в виде hex-строки.

  • getEncoded() Возвращает бинарное представление объекта.

  • toString() Возвращает человекочитаемое описание структуры (используется в отладке).

  • getLengthHexFromContent() Рассчитывает длину содержимого ASN.1 элемента.

  • getEncodedHex() (override в наследниках) Реализует конкретное кодирование типа.

ASN1Object не используется напрямую, но задаёт общую модель поведения для всех DER-типов.


DERAbstractString: базовый класс строковых типов

DERAbstractString служит промежуточным уровнем для всех строковых ASN.1 типов. Он расширяет ASN1Object и добавляет работу со строковыми данными.

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

  • хранение строкового значения
  • поддержка UTF-8 и ASCII кодировок
  • преобразование в HEX перед DER сериализацией

Методы:

  • getString() Возвращает исходную строку.

  • setString(newValue) Устанавливает новое значение строки.


DERUTF8String

Используется для кодирования UTF-8 строк.

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

var s = new KJUR.asn1.DERUTF8String({str: "Пример"});
console.log(s.getEncodedHex());

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

  • поддержка Unicode
  • используется в сертификатах X.509 (например, Subject DN)

DERPrintableString

Предназначен для ограниченного набора символов (A-Z, a-z, 0-9 и ограниченные знаки).

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

  • именах субъектов сертификатов
  • полях, требующих строгой совместимости

Ограничение символов делает этот тип более совместимым со старыми криптографическими системами.


DERIA5String

Используется для ASCII-строк (7-bit). Часто применяется для:

  • email
  • доменных имён
  • URI

DERInteger

DERInteger представляет целочисленные значения в ASN.1.

Ключевые особенности:

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

Пример:

var i = new KJUR.asn1.DERInteger({int: 12345});

Методы:

  • getInteger() — получение числа
  • setInteger() — установка значения

DERBitString

DERBitString используется для хранения битовых последовательностей.

Основное применение:

  • ключевые параметры
  • флаги сертификатов (KeyUsage, BasicConstraints)

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

  • unused bits count
  • бинарные данные

DEROctetString

DEROctetString представляет произвольные байтовые данные.

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

  • хэш-значений
  • бинарных структур
  • вложенных ASN.1 объектов

DERNull

DERNull представляет ASN.1 NULL тип.

Используется как маркер отсутствия значения.

Пример применения:

  • алгоритмы без параметров (например, SHA-256 OID параметр = NULL)

DERObjectIdentifier

DERObjectIdentifier (OID) — один из наиболее важных типов ASN.1.

Представляет иерархические идентификаторы:

Примеры OID:

  • 1.2.840.113549.1.1.1 (RSA encryption)
  • 2.5.4.3 (commonName)

Методы:

  • getOID()
  • setOID()

Особенность: OID кодируется в компактной форме с использованием base-128 encoding.


DERSequence

DERSequence представляет упорядоченную последовательность ASN.1 объектов.

Характеристики:

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

Методы:

  • addObject(obj)
  • getObject(index)
  • getEncodedHex()

Пример:

var seq = new KJUR.asn1.DERSequence({
  array: [
    new KJUR.asn1.DERInteger({int: 1}),
    new KJUR.asn1.DERUTF8String({str: "test"})
  ]
});

DERSet

DERSet аналогичен DERSequence, но элементы неупорядочены.

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

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

Вспомогательные утилиты KJUR.asn1

Помимо классов, существует набор утилитарных функций:

ASN1Util

Обеспечивает:

  • преобразование hex ↔︎ byte
  • работу с длинами ASN.1
  • вспомогательные операции кодирования

DERUtil (внутренние функции)

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

  • формирования тегов
  • вычисления длины полей
  • упаковки данных в DER формат

Принцип DER кодирования в jsrsasign

Каждый ASN.1 объект кодируется по схеме:

[Tag][Length][Value]
  • Tag — идентификатор типа
  • Length — длина содержимого
  • Value — закодированные данные

KJUR.asn1 автоматически управляет всеми тремя уровнями.


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

ASN.1 объекты могут содержать другие ASN.1 объекты, формируя дерево:

SEQUENCE
 ├── INTEGER
 ├── UTF8String
 ├── SEQUENCE
 │     ├── OID
 │     ├── NULL

Каждый уровень кодируется рекурсивно через getEncodedHex().


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

KJUR.asn1 является основой для:

  • X.509 сертификатов (KJUR.asn1.x509)
  • PKCS#1 (RSA ключи)
  • PKCS#10 (CSR запросы)
  • CMS/PKCS#7 структур

Например, сертификат X.509 полностью строится из ASN.1 SEQUENCE с вложенными объектами Subject, Issuer, Validity и PublicKeyInfo.


Особенности реализации jsrsasign

Архитектура KJUR.asn1 отличается следующими принципами:

  • отсутствие внешних зависимостей
  • чистая JavaScript реализация DER кодирования
  • объектная модель ASN.1 дерева
  • строгая совместимость с OpenSSL форматом

Типичные ошибки при работе с ASN.1 слоями

  • неправильный выбор строкового типа (PrintableString vs UTF8String)
  • некорректная длина OID или битовых строк
  • использование DERSet вместо DERSequence
  • неверное кодирование больших чисел в DERInteger

Механика сериализации объектов

При вызове getEncodedHex():

  1. Объект преобразует внутренние данные в байты
  2. Вычисляется длина содержимого
  3. Формируется DER заголовок
  4. Объединяются Tag + Length + Value

Результат всегда представляет валидную DER структуру.


Роль ASN.1 слоя в jsrsasign

KJUR.asn1 выполняет функцию низкоуровневого конструктора криптографических структур. Все более высокоуровневые модули библиотеки опираются на него как на фундамент кодирования и декодирования данных PKI.