Пространство имён ASN1HEX

Пространство имён ASN1HEX в библиотеке Jsrsasign предназначено для работы с ASN.1-структурами, представленными в виде HEX-строк. Оно предоставляет низкоуровневые функции для разбора, навигации и извлечения данных из DER-кодированных объектов.

ASN.1 (Abstract Syntax Notation One) широко используется в криптографии — в сертификатах X.509, ключах RSA/ECDSA, PKCS-структурах. В библиотеке Jsrsasign большинство криптографических операций опираются на корректное извлечение и интерпретацию ASN.1-данных, поэтому ASN1HEX играет фундаментальную роль.


Базовое представление ASN.1 в HEX

ASN.1-объект в DER-кодировке имеет следующую структуру:

[Tag][Length][Value]

В HEX-строке это выглядит как последовательность байтов:

  • Tag — тип данных (например, INTEGER, SEQUENCE)
  • Length — длина содержимого
  • Value — само содержимое

Пример:

30 0A 02 01 01 02 01 02

Расшифровка:

  • 30 — SEQUENCE
  • 0A — длина (10 байт)
  • далее содержимое

Основные функции ASN1HEX

Получение длины объекта

ASN1HEX.getVblen(hex, idx)

Возвращает длину значения (Value) ASN.1-объекта по позиции idx.

ASN1HEX.getL(hex, idx)

Возвращает HEX-представление поля Length.

ASN1HEX.getVidx(hex, idx)

Возвращает индекс начала Value.


Извлечение значения

ASN1HEX.getV(hex, idx)

Возвращает Value как HEX-строку.

ASN1HEX.getTLV(hex, idx)

Возвращает полный TLV-блок (Tag + Length + Value).


Работа с дочерними элементами

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

ASN1HEX.getChildIdx(hex, idx)

Возвращает массив индексов дочерних элементов.

Пример:

var children = ASN1HEX.getChildIdx(hex, 0);

Результат:

[4, 10, 16]

Каждое число — позиция дочернего элемента.


Навигация по структуре

ASN1HEX.getNthChildIdx(hex, idx, nth)

Возвращает индекс nth-дочернего элемента.

ASN1HEX.getIdxbyList(hex, currentIndex, indexList)

Позволяет пройти по дереву ASN.1 с помощью массива индексов.

Пример:

ASN1HEX.getIdxbyList(hex, 0, [0, 1])

Означает:

  • взять 0-й дочерний элемент
  • затем у него взять 1-й дочерний элемент

Работа с путями (Path-based доступ)

Один из наиболее удобных механизмов — извлечение значений по пути:

ASN1HEX.getVbyList(hex, currentIndex, nthList, tag)

Параметры:

  • hex — исходная строка
  • currentIndex — начальный индекс
  • nthList — путь (массив индексов)
  • tag — ожидаемый тег (опционально)

Пример:

ASN1HEX.getVbyList(hex, 0, [0, 1], "02")

Извлекает INTEGER по заданному пути.


Проверка тегов

ASN1HEX.getTLVbyList(hex, currentIndex, nthList, tag)

Позволяет извлечь TLV, проверяя соответствие тегу.

Если тег не совпадает — выбрасывается ошибка.


Обработка ASN.1 SEQUENCE

SEQUENCE — один из самых распространённых типов.

Пример структуры:

30 0A
   02 01 01
   02 01 02

Разбор:

var children = ASN1HEX.getChildIdx(hex, 0);

var first = ASN1HEX.getV(hex, children[0]);
var second = ASN1HEX.getV(hex, children[1]);

Работа с INTEGER

INTEGER кодируется тегом 02.

Пример:

02 01 01

Извлечение:

var idx = ASN1HEX.getIdxbyList(hex, 0, [0]);
var valueHex = ASN1HEX.getV(hex, idx);

Работа с BIT STRING

BIT STRING имеет тег 03.

Особенность — первый байт внутри Value указывает количество неиспользуемых бит.

ASN1HEX.getV(hex, idx)

Возвращает значение, включая этот байт.

Для извлечения “чистых” данных:

var bitString = ASN1HEX.getV(hex, idx);
var unusedBits = parseInt(bitString.substr(0, 2), 16);
var data = bitString.substr(2);

Работа с OBJECT IDENTIFIER

OID кодируется тегом 06.

ASN1HEX.getV(hex, idx)

Возвращает HEX-представление, которое затем можно преобразовать в строковый OID через другие утилиты Jsrsasign.


Пример разбора сертификата

DER-кодированный сертификат X.509:

var certHex = ...;

Извлечение версии:

ASN1HEX.getVbyList(certHex, 0, [0, 0, 0], "a0");

Извлечение серийного номера:

ASN1HEX.getVbyList(certHex, 0, [0, 1], "02");

Обработка ошибок

Функции ASN1HEX часто выбрасывают исключения:

  • неверный индекс
  • несоответствие тегов
  • некорректная структура

Поэтому при работе с неизвестными ASN.1-данными рекомендуется использовать try/catch.


Особенности DER-кодировки

ASN1HEX ориентирован именно на DER:

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

BER или CER могут частично не поддерживаться.


Производительность и ограничения

  • Все операции выполняются на строках HEX — это медленнее, чем работа с бинарными буферами
  • Нет автоматической типизации — всё возвращается как строки
  • Требуется ручная интерпретация значений

Практические сценарии использования

Разбор сертификатов

  • извлечение полей X.509
  • проверка структуры

Работа с ключами

  • парсинг RSA/ECDSA ключей
  • извлечение модулей и экспонент

PKCS#7 / PKCS#12

  • анализ контейнеров
  • извлечение вложенных объектов

Отладка ASN.1

  • анализ бинарных структур
  • диагностика ошибок кодирования

Комбинирование с другими модулями Jsrsasign

ASN1HEX часто используется совместно с:

  • X509 — высокоуровневый разбор сертификатов
  • KEYUTIL — работа с ключами
  • KJUR.asn1 — генерация ASN.1

ASN1HEX остаётся инструментом низкого уровня, когда требуется полный контроль над структурой.


Рекомендации по использованию

  • Использовать getVbyList для удобной навигации
  • Проверять теги при извлечении
  • Избегать ручного вычисления индексов, если есть встроенные функции
  • Документировать структуру ASN.1 при работе с нестандартными форматами
  • При необходимости использовать визуализаторы ASN.1 для анализа структуры перед кодированием логики

Пример полной навигации

var hex = "300a020101020102";

var rootChildren = ASN1HEX.getChildIdx(hex, 0);

var firstIdx = rootChildren[0];
var secondIdx = rootChildren[1];

var firstValue = ASN1HEX.getV(hex, firstIdx);
var secondValue = ASN1HEX.getV(hex, secondIdx);

Результат:

firstValue = "01"
secondValue = "02"

Роль ASN1HEX в архитектуре Jsrsasign

ASN1HEX — это фундаментальный слой:

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

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