Программное создание CSR

Я пытаюсь программно создать CSR. Я читал об ASN.1, RFC 2986, X.509.
Я также вручную проанализировал несколько файлов CSR с кодировкой DER, которые были созданы с использованием OpenSSL.
Все выглядит ясным, за исключением пары вещей:

  1. Часть открытого ключа содержит следующие байты 8D 00 30 81 89 02 81 81 перед содержимым BIT STRING (и после 03 81). Что это? Я заметил, что все файлы CSR, закодированные с помощью DER, содержат их. Я ничего о них не нашел в RFC.

  2. Часть подписи содержит следующие нечеткие байты перед содержимым подписи, но после 03 81. Насколько я понимаю, эта часть содержит информацию о последнем октете в BIT STRING (сколько битов в последнем байте на самом деле должно быть принято). Но я не понимаю, как расшифровать эти байты. Например, подпись может выглядеть следующим образом:
    03 81 81 00 64 12 ... 24 B1 28
    где 03h - это формат BIT STRING, 81h длина битовой строки, 64 12 ... 24 B1 28 - подпись (но она имеет длину 80h). Я не понимаю часть 81 00.

Заранее спасибо.


person gN0Me    schedule 03.08.2011    source источник
comment
Какой у вас алгоритм открытого ключа? RSA?   -  person emboss    schedule 04.08.2011
comment
Да, сейчас я использую RSA   -  person gN0Me    schedule 04.08.2011


Ответы (2)


  1. BIT STRING в SubjectPublicKeyInfo зависит от вашего алгоритма открытого ключа. Содержимое снова закодировано в формате DER, возможности см. В RFC 3370.

  2. Если ваша подпись выглядит как

    03 81 81 00 64 12 ... 24 B1 28

это следует интерпретировать следующим образом. DER - это TLV (Тег - Длина - Значение) кодировки. Итак, первый байт (октет на их языке) представляет тег - 03 для BIT STRING, как вы правильно заметили.

Второй байт определяет длину:

В длинной форме октеты длины должны состоять из начального октета и одного или нескольких последующих октетов. Начальный октет должен быть закодирован следующим образом:

а) бит 8 должен быть равен единице;

b) биты с 7 по 1 должны кодировать количество последующих октетов в октетах длины как беззнаковое двоичное целое число с битом 7 как наиболее значимый бит;

81 имеет бит 8, установленный в единицу, поэтому оставшиеся биты указывают количество байтов, определяющих общую длину. В вашем случае это просто 1 байт. Итак, следующий байт - это ваша длина - 81 равен длине подписи 129 байтов. Итак, следующие 129 байтов представляют ваше значение, начиная с 00.

person emboss    schedule 04.08.2011
comment
Спасибо за ваш ответ! Я абсолютно понимаю часть подписи. Что касается SubjectPublicKeyInfo, я не совсем понимаю. Я использую алгоритм RSA для генерации открытого ключа. Следует ли дважды кодировать открытый ключ с помощью DER? Я видел об этом RFC 3370. RSA нужно кодировать так: RSAPublicKey ::= SEQUENCE { modulus INTEGER, -- n publicExponent INTEGER } -- e Но почему вместо BIT STRING используется INTEGER? 8D 00 30 81 89 02 81 81 не похож на формат DER. Я не знаю, например, что означает 8D. Не могли бы вы мне помочь? - person gN0Me; 04.08.2011
comment
В зависимости от того, какой язык вы используете, часто уже существует метод, позволяющий получить кодировку DER. И да, вы правы, значение BIT STRING снова является независимой (вложенной) кодировкой DER. Это означает, что если вы декодируете значение СТРОКИ БИТОВ, вы получите ПОСЛЕДОВАТЕЛЬНОСТЬ для RSAPublicKey. - person emboss; 04.08.2011
comment
Это действительно отличный инструмент! Спасибо, что упомянули об этом! - person emboss; 05.08.2011
comment
Вы пишете следующие 129 байтов, представляющие ваше значение, начиная с 00. Это не совсем так: при декодировании BIT STRING первый байт после длины указывает количество битов, которые были добавлены в качестве заполнения. В данном случае 0. Таким образом, значение BIT STRING начинается с 30 81 (что распознается как начало RSAPublicKey SEQUENCE). - person Rasmus Faber; 09.08.2011

Когда вы говорите «программно», что именно вы имеете в виду? В коде? Если да, то какой язык вы используете? Провайдер BouncyCastle JCE содержит классы для генерации запроса PKCS # 10 при условии, что вы используете Java. Все, что вам нужно сделать, это указать необходимые компоненты (DN, открытый ключ и т. Д.). Я считаю, что также существует реализация .Net, которая может быть более подходящей для сред Microsoft.

person Shadowman    schedule 09.08.2011
comment
Я создал свой собственный декодер ASN.1 в своем проекте для iPhone. Похоже, это единственное решение - person gN0Me; 20.08.2011
comment
Если вы разрабатываете на iPhone, у вас должна быть возможность использовать OpenSSL. В нем должны быть все необходимые вам методы. Парсинг ASN.1, создание CSR и т. Д. - person Shadowman; 22.08.2011