ASN.1 / DER кодирование целых чисел - PullRequest
2 голосов
/ 26 марта 2019

В настоящее время я начинаю работать с кодировкой DER (Distinguished Encoding Rules) и у меня возникают проблемы с пониманием кодировки целых чисел.

В справочном документе https://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf эта кодировка определяется следующим образом:

8.3.1 Кодирование целочисленного значения должно быть примитивным. Октеты содержимого должны состоять из одного или нескольких октетов.

8.3.2 Если октеты содержимого кодирования целого значения состоят из более чем одного октета, то биты первого октета и бит 8 второго октета:

  1. не все должны быть единицами; и

  2. не должно быть все равно нулю.

ПРИМЕЧАНИЕ. - Эти правила гарантируют, что целочисленное значение всегда кодируется в наименьшем возможном количестве октетов.

8.3.3 Октеты содержимого должны быть двоичным числом с дополнительным двоичным числом, равным целочисленному значению, и состоять из битов 8–1 первого октета, за которыми следуют биты 8–1 второго октета, за которыми следуют биты 8–1. 1 каждый октет по очереди до последнего октета содержимого октетов включительно.

На другом сайте, https://docs.microsoft.com/en-us/windows/desktop/seccertenroll/about-integer, объясняется, что для положительных чисел, двоичное представление которых начинается с 1, нулевой байт добавляется впереди. Это также упоминается в ответах на предыдущий вопрос о стековом потоке: Основное правило кодирования ASN целого числа .

К сожалению, из этих ответов я не вижу, как эта последняя инструкция может быть выведена из правил справочного документа.

Например, если я хочу кодировать число 128, почему я не могу сделать это как

[тег байта] [длина байта] 10000000?

Я знаю, что правильная кодировка будет [tag byte] [length byte] 00000000 10000000, но какое условие повреждено вариантом выше? Вероятно, это как-то связано с дополнением к двум, но разве это дополнение к двоим не больше 10000000?

Надеюсь, вы поможете мне понять, почему описание на сайте Microsoft эквивалентно первоначальному определению. Спасибо.

1 Ответ

0 голосов
/ 26 марта 2019

Правило дополняющее два * (8.3.3) гласит, что если задан старший бит первого байта содержимого (самый низкий индекс), то число является отрицательным.

02 01 80 имеет содержание 0b1000_0000. Поскольку старший бит установлен, число является отрицательным.

Отразить все биты (0b0111_1111), затем добавить один: 0b1000_0000; это означает, что он представляет собой отрицательное 128.

Для менее вырожденного примера, 0b1000_0001 => 0b0111_1110 => 0b0111_1111, показывая, что 0x81 отрицательно 127.

Для числа (положительного) 127, поскольку старший бит не установлен, число интерпретируется как положительное, поэтому его содержимое равно 0b0111_1111 или 0x7F, в результате чего 02 01 7F

...