ASN.1 кодировка в JavaScript-библиотеке jsrsasign представляет собой один из ключевых механизмов работы с криптографическими структурами: сертификатами X.509, ключами, подписями и любыми DER-данными. В основе лежит необходимость разбирать бинарно-hex представление ASN.1 объектов в дерево, пригодное для программной обработки.
ASN.1 (Abstract Syntax Notation One) в DER-кодировке всегда имеет иерархическую структуру: последовательности (SEQUENCE) содержат вложенные элементы, которые, в свою очередь, могут быть простыми типами (INTEGER, OID, UTF8String) или снова контейнерами.
В jsrsasign эта структура при разборе hex-представления превращается в дерево узлов, где каждый узел содержит:
Такое представление позволяет выполнять навигацию по структуре без повторного декодирования байтов.
Функция ASN1HEX.parse предназначена для преобразования
ASN.1 DER hex строки в структурированное дерево.
Типичный вызов:
var tree = ASN1HEX.parse(hex);
На выходе формируется массивоподобная структура, где каждый узел описывается набором параметров:
Внутренне структура напоминает AST (abstract syntax tree), где каждый элемент связан с подэлементами через индексы.
Пример логической структуры:
SEQUENCE
├── INTEGER
├── OID
├── SEQUENCE
│ ├── UTF8String
│ └── BIT STRING
Каждый узел можно представить как:
[nodeType, start, headerLength, valueLength, children]
где:
nodeType — ASN.1 тег (например, 0x30 для SEQUENCE)start — позиция в hex-строкеheaderLength — длина заголовка (tag + length
bytes)valueLength — длина полезных данныхchildren — массив дочерних узлов (если применимо)Важно, что дерево строится лениво: вложенные элементы не всегда декодируются полностью сразу, а индексируются.
После вызова ASN1HEX.parse основная работа заключается в
обходе структуры. jsrsasign предоставляет несколько уровней доступа:
Логика обхода основана на индексации:
var children = node[4];
Если элемент является SEQUENCE, children будет содержать
массив вложенных узлов.
Наиболее естественный способ анализа ASN.1 структуры — рекурсивный DFS (depth-first search).
function walk(node, depth) {
var indent = " ".repeat(depth);
console.log(indent + "TAG: " + node[0]);
console.log(indent + "POS: " + node[1]);
if (node[4]) {
for (var i = 0; i < node[4].length; i++) {
walk(node[4][i], depth + 1);
}
}
}
Такой подход позволяет полностью развернуть ASN.1 структуру сертификата или ключа.
Для больших структур предпочтителен обход без рекурсии:
function traverse(root) {
var stack = [root];
while (stack.length > 0) {
var node = stack.pop();
if (node[4]) {
for (var i = 0; i < node[4].length; i++) {
stack.push(node[4][i]);
}
}
}
}
Этот подход полезен при обработке сертификатов, где глубина вложенности может быть значительной.
ASN1HEX.parse сам по себе не возвращает интерпретированные значения. Для этого используется позиция и длина:
Пример извлечения содержимого:
var valueHex = hex.substring(node[1] + node[2] * 2,
node[1] + (node[2] + node[3]) * 2);
Далее значение может быть преобразовано в читаемый формат:
Частая задача — найти определённый OID или поле в сертификате.
Пример поиска OID:
function findOID(node, targetOID) {
var results = [];
function dfs(n) {
if (n[0] === 0x06) { // OID tag
var oid = ASN1HEX.oidHexToInt(n[5]);
if (oid === targetOID) {
results.push(n);
}
}
if (n[4]) {
for (var i = 0; i < n[4].length; i++) {
dfs(n[4][i]);
}
}
}
dfs(node);
return results;
}
ASN1HEX.parse особенно полезен при анализе X.509 сертификатов:
Каждый из этих блоков является SEQUENCE внутри основного дерева.
Пример логики:
Certificate
├── TBSCertificate
│ ├── Version
│ ├── Serial Number
│ ├── Signature
│ ├── Issuer
│ ├── Validity
│ ├── Subject
│ ├── SubjectPublicKeyInfo
│ └── Extensions
├── SignatureAlgorithm
└── SignatureValue
ASN1HEX.parse позволяет пройти эту структуру без использования высокоуровневых парсеров.
При работе с большими ASN.1 структурами важно учитывать:
Особенно критично это при обработке цепочек сертификатов и CRL.
ASN.1 структура чувствительна к смещению, и любая ошибка в расчётах индексов приводит к разрушению дерева.
Каждый ASN.1 узел можно связать с криптографической логикой:
Обход дерева позволяет вручную реконструировать смысл сертификата без использования готовых API jsrsasign верхнего уровня.
ASN1HEX.parse применяется там, где требуется:
Работа на уровне дерева даёт полный контроль над структурой, минуя абстракции библиотек высокого уровня