Класс KJUR.asn1.DERBitString

Тип BIT STRING в ASN.1 представляет последовательность произвольного количества битов, не обязательно кратную байту. В отличие от OCTET STRING, который оперирует байтами, BIT STRING позволяет работать с битовой точностью, что критично для криптографических структур: ключевых параметров, масок прав, флагов и некоторых полей сертификатов X.509.

В DER-формате (Distinguished Encoding Rules) BIT STRING кодируется с обязательным указанием количества неиспользуемых битов в последнем октете. Это делает представление строгим и однозначным при декодировании.


Представление BIT STRING в DER

Структура DER-энкодированного BIT STRING:

  • Tag: 0x03

  • Length: длина содержимого

  • Content:

    • 1 байт — количество неиспользуемых битов в последнем байте
    • далее — сами данные битовой строки

Ключевой элемент — unused bits. Например, если передано 13 бит, последний байт будет содержать только 5 значимых бит, а 3 бита будут помечены как неиспользуемые.


Класс KJUR.asn1.DERBitString

KJUR.asn1.DERBitString — компонент библиотеки Jsrsasign, предназначенный для создания ASN.1 структуры BIT STRING в DER-формате.

Он используется внутри более высокоуровневых объектов (сертификаты, ключи, CMS), а также может применяться напрямую при построении ASN.1 деревьев.


Конструктор и параметры

Создание объекта выполняется через передачу параметров в виде объекта:

new KJUR.asn1.DERBitString(params)

Основные параметры:

bin

Строка, содержащая битовое представление:

{
  bin: "10101100"
}

Каждый символ интерпретируется как бит (0 или 1). Длина не обязана быть кратной 8.


hex

Шестнадцатеричное представление:

{
  hex: "ACF3"
}

Каждая пара символов соответствует одному байту.


array

Массив байтов:

{
  array: [0xAC, 0xF3]
}

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


unused

Количество неиспользуемых битов в последнем байте:

{
  hex: "AF",
  unused: 3
}

Если параметр не указан, библиотека вычисляет его автоматически на основе длины входных данных.


Внутренний механизм кодирования

При вызове encode происходит формирование DER-структуры:

  1. Вычисляется байтовое представление входных данных

  2. Определяется количество лишних битов в последнем октете

  3. Формируется payload:

    • первый байт = unused bits
    • далее данные
  4. Добавляется ASN.1 заголовок 0x03


Пример формирования BIT STRING из бинарной строки

var bs = new KJUR.asn1.DERBitString({
  bin: "11010101"
});

Здесь:

  • длина = 8 бит
  • unused = 0
  • содержимое кодируется как один байт 0xD5

Пример с неполным байтом

var bs = new KJUR.asn1.DERBitString({
  bin: "10101"
});

Разбор:

  • 5 значимых бит
  • дополняется до 1 байта: 10101000
  • unused = 3

Итоговая DER-структура:

  • Tag: 0x03

  • Length: 2

  • Content:

    • 0x03 (unused bits)
    • 0xA8 (данные)

Пример с hex-строкой

var bs = new KJUR.asn1.DERBitString({
  hex: "FF80"
});

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

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

Работа с массивом байтов

var bs = new KJUR.asn1.DERBitString({
  array: [0xDE, 0xAD, 0xBE, 0xEF]
});

Этот вариант удобен при работе с бинарными буферами, например при интеграции с WebCrypto или Node.js Buffer.


Автоматическое вычисление unused bits

Если вход задан без явного параметра unused, библиотека:

  • анализирует длину битовой строки
  • определяет количество бит до ближайшего байта
  • устанавливает значение от 0 до 7

Пример:

Длина бит Последний байт unused
8 полный 0
9 1 бит в новом 7
13 частичный байт 3

Кодирование внутри ASN.1 дерева

DERBitString часто используется как листовой элемент:

var asn1 = new KJUR.asn1.DERSequence({
  array: [
    new KJUR.asn1.DERInteger({int: 3}),
    new KJUR.asn1.DERBitString({bin: "1010"})
  ]
});

Так формируются структуры сертификатов, например расширения X.509.


Важные особенности реализации

1. Жёсткая привязка к DER

Класс не поддерживает BER- или CER-варианты. Все данные кодируются строго.

2. Нормализация входа

Любой формат (bin, hex, array) приводится к байтовому массиву перед кодированием.

3. Контроль корректности битов

Допустимы только 0 и 1 в бинарной строке. Любые другие символы приводят к ошибке преобразования.


Типичные ошибки при использовании

Некорректная длина bin-строки

bin: "10201"

Недопустимо из-за символа 2.


Несогласованность hex и unused

Если явно задать unused, не соответствующий данным, декодеры могут интерпретировать структуру неверно:

hex: "FF",
unused: 4

Использование битовой строки вместо байтов

BIT STRING требует строгого понимания, что последний байт может быть неполным. Игнорирование этого приводит к ошибкам в криптографических структурах.


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

DERBitString применяется в:

  • X.509 сертификатах (ключевые параметры, usage flags)
  • RSA/DSA/ECDSA структурах
  • PKCS#7 / CMS контейнерах
  • расширениях сертификатов (Key Usage, Basic Constraints)

Особенно часто используется для:

  • KeyUsage (digitalSignature, keyEncipherment и др.)
  • Bitmask-значений политик безопасности

Поведение при сериализации

После вызова getEncodedHex() (через базовый ASN.1 API) результат всегда включает:

  • корректный tag 0x03
  • длину
  • байт unused
  • выровненные данные

Это гарантирует совместимость с OpenSSL и другими ASN.1 реализациями.


Взаимодействие с другими классами Jsrsasign

DERBitString тесно связан с:

  • KJUR.asn1.DERSequence
  • KJUR.asn1.DERInteger
  • KJUR.asn1.DEROctetString

Часто выступает как часть сложной структуры, где требуется компактное представление флагов.


Особенности интерпретации в криптосистемах

Разные системы могут по-разному трактовать unused bits:

  • некоторые игнорируют их полностью
  • другие строго проверяют
  • часть библиотек требует нулевого значения unused для всех случаев

Поэтому в критичных системах часто задают unused: 0 явно, даже если это не обязательно.