KJUR.asn1 реализует набор классов для построения и сериализации ASN.1 структур в формате DER/BER, используемых в криптографии, сертификатах X.509, PKCS
Основой системы выступает абстрактный класс ASN.1 объекта,
определяющий общий контракт для всех элементов структуры. Внутри
KJUR.asn1 это реализуется через KJUR.asn1.ASN1Object.
Ключевая роль базового объекта заключается в унификации поведения:
Каждый наследник реализует метод:
getEncodedHex()
который возвращает DER-представление объекта в виде hex-строки.
ASN1Object является корневым классом для всех ASN.1
типов. Он не представляет конкретного ASN.1 типа, но задаёт базовую
логику кодирования.
Основные свойства:
isModified — флаг необходимости пересборки бинарного
представленияhTLV — кешированное DER-значениеhT — тегhL — длинаhV — значениеМетоды:
getEncodedHex() — возвращает DER-кодgetLengthHexFromValue() — вычисление длины
значенияgetEncodedHexValue() — кодирование только значенияtohex() — вспомогательное представлениеМодель построена на принципе ленивого вычисления: бинарный результат пересоздаётся только при изменении структуры.
Представляет целые числа в ASN.1 формате INTEGER. Используется в ключах, сертификатах и цифровых подписях.
Особенности:
Пример:
const int = new KJUR.asn1.DERInteger({int: 1234});
console.log(int.getEncodedHex());
Используется для булевых значений TRUE/FALSE.
Правила кодирования:
0xff0x00Контейнер для бинарных данных. Часто используется для вложенных структур и хранимых ключей.
Особенности:
Используется для битовых последовательностей, например, в public key structures.
Особенность DER-кодирования:
SEQUENCE — основной контейнер ASN.1, упорядоченная
коллекция элементов.
Особенности реализации:
asn1ArrayПример:
const seq = new KJUR.asn1.DERSequence({
array: [
new KJUR.asn1.DERInteger({int: 1}),
new KJUR.asn1.DERInteger({int: 2})
]
});
SET аналогичен SEQUENCE, но не гарантирует порядок
элементов.
В KJUR.asn1 порядок обычно сохраняется на уровне структуры, но семантически трактуется как неупорядоченный набор.
Представляет идентификаторы алгоритмов и схем.
Пример:
Кодирование OID происходит через базу 40:
Пример:
const oid = new KJUR.asn1.DERObjectIdentifier({
oid: "1.2.840.113549.1.1.11"
});
Используется как маркер отсутствующего значения.
Кодирование всегда фиксировано:
Утилитарный слой предоставляет функции для преобразования данных между форматами.
Основные возможности:
Ключевые методы:
newObject(param) — создание ASN.1 объекта по
описаниюgetPEMStringFromHex(hex, label) — генерация PEMhexToDER() — преобразование hex в DER-структуруgetTLVLength() — вычисление длины TLVВсе ASN.1 объекты в KJUR.asn1 кодируются по схеме TLV:
Пример структуры:
30 ... SEQUENCE
02 ... INTEGER
04 ... OCTET STRING
Кодирование длины поддерживает:
Одной из ключевых особенностей является рекурсивная сборка ASN.1 дерева.
Каждый объект может содержать:
При вызове getEncodedHex() происходит:
ASN.1 объекты используют флаг isModified, который
управляет пересборкой бинарного представления.
Логика:
isModified = truegetEncodedHex() → пересборка только при
необходимостиhTLVЭто критично для производительности при работе с большими сертификатами.
Хотя PEM относится к внешнему уровню, ASN.1 слой участвует в его формировании.
Процесс:
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
Архитектура KJUR.asn1 позволяет создавать новые ASN.1 типы через
наследование от ASN1Object.
Типичная схема расширения:
var MyASN1Type = function(params) {
KJUR.asn1.ASN1Object.call(this);
this.params = params;
};
MyASN1Type.prototype = Object.create(KJUR.asn1.ASN1Object.prototype);
MyASN1Type.prototype.constructor = MyASN1Type;
MyASN1Type.prototype.getEncodedHex = function() {
// кастомная логика кодирования
};
Это позволяет внедрять нестандартные ASN.1 конструкции без изменения ядра библиотеки.
Базовые классы минимизируют строгую валидацию, отдавая приоритет гибкости.
Основные проверки:
Ошибки обычно проявляются на этапе DER кодирования, а не при создании объектов.
Оптимизация достигается за счёт:
На практике это позволяет эффективно кодировать большие структуры сертификатов и ключей даже в среде браузера.