ASN.1 (Abstract Syntax Notation One) определяет абстрактное описание данных, используемых в криптографии, сертификатах X.509, подписях и протоколах безопасности. Однако сам ASN.1 не задаёт способ физического представления данных — для этого используются правила кодирования (Encoding Rules), среди которых ключевыми являются BER, CER и DER.
В контексте JavaScript-библиотеки jsrsasign понимание различий между этими правилами критично, поскольку работа с сертификатами, ключами и подписями напрямую связана с корректным парсингом ASN.1 структур.
BER является базовым и наиболее гибким способом кодирования ASN.1 структур. Он допускает несколько вариантов представления одних и тех же данных.
Пример ключевой особенности BER — неопределённая длина:
SEQUENCE {
OCTET STRING (indefinite length)
...
END OF CONTENT
}
Такая гибкость делает BER удобным для потоковой передачи данных, но создаёт проблемы при криптографической валидации.
DER — это строгий поднабор BER. Его цель — устранить неоднозначность представления данных.
Ключевая особенность DER — однозначность:
одна и та же структура всегда кодируется одинаково, независимо от реализации.
DER используется в:
Причина проста: криптографические подписи требуют бит-в-бит идентичного представления данных.
CER занимает промежуточное положение между BER и DER. Он также является каноническим, но предназначен для случаев, где данные могут быть очень большими или потоковыми.
CER часто используется там, где DER становится неудобным из-за ограничений по размеру элементов.
Один и тот же ASN.1 объект может иметь разные бинарные представления при использовании BER, но только один корректный вариант при DER и CER.
Пример структуры:
SEQUENCE {
INTEGER 10
OCTET STRING "test"
}
В BER возможны разные формы кодирования длины и структуры, но DER фиксирует единственно допустимое представление.
Библиотека jsrsasign предоставляет инструменты для работы с ASN.1 структурами, включая декодирование и анализ сертификатов.
Основной модуль:
KJUR.asn1.ASN1Util
и низкоуровневые структуры:
ASN1Object
ASN1Integer
ASN1Sequence
Большинство операций в jsrsasign предполагают DER-кодирование по умолчанию, поскольку:
Пример декодирования сертификата:
const certPEM = "-----BEGIN CERTIFICATE-----...";
const cert = new X509();
cert.readCertPEM(certPEM);
const subject = cert.getSubject();
const issuer = cert.getIssuer();
Внутри библиотека переводит PEM → DER → ASN.1 дерево.
BER редко используется напрямую в jsrsasign, но может встречаться при:
Особенность: jsrsasign может корректно прочитать BER-кодированные данные, но дальнейшая криптографическая обработка часто требует приведения к DER.
CER практически не используется напрямую в jsrsasign API, однако концептуально важен при:
На практике CER чаще встречается в теоретической криптографии и низкоуровневых ASN.1 реализациях, чем в JavaScript-экосистеме.
DER стал стандартом де-факто из-за необходимости:
Если бы использовался BER, одна и та же структура могла бы иметь разные бинарные представления, что делало бы цифровые подписи ненадёжными.
Внутри библиотеки ASN.1 представляется деревом объектов:
Каждый узел может быть сериализован в DER-форму:
const seq = new KJUR.asn1.DERSequence({
array: [
new KJUR.asn1.DERInteger({int: 10}),
new KJUR.asn1.DERUTF8String({str: "test"})
]
});
const hex = seq.getEncodedHex();
Результат всегда будет DER-совместимым.