2016-10-03 15 views
1

Я пытаюсь создать CSR (запрос подписи сертификата) во встроенное устройство. Я реализовал некоторые функции OpenSSL на одном встроенном устройстве. К сожалению, у меня есть только несколько доступных функций. До сих пор мне удалось создать закрытый ключ RSA, и теперь мне нужно создать CSR.Как создается подпись CSR?

В моей библиотеке нет ни одной из таких функций, как X509_REQ_new(), X509_REQ_get_subject_name() и т. Д. Поэтому я создаю CSR, создавая файл DER напрямую.

КСО в формате DER декодируется следующим образом:

  1. ASN1 Последовательность
  2. версия
  3. Тема (ы) имя (ы)
  4. тип шифрования
  5. Модуль & экспоненте (от моего ключа RSA)
  6. Атрибуты
  7. Signa ры (вот где моя проблема лежит)

Если бы я имел все функции OpenSSL доступны Я хотел бы использовать X509_REQ_sign(x509_req, pKey, EVP_sha1()), но, как я уже говорил, я не какой-либо из объектов X509 доступны.

Что мне нужно для подписи, чтобы построить эту часть?

+0

Мне сложно разобрать ваш вопрос. Что ваша библиотека должна делать с чем угодно? Или, почему он помечен OpenSSL, если это не вопрос OpenSSL? Если ваш вопрос буквально * «Что мне нужно подписать для сборки этой части?» *, То его *** 'tbsCertificate' *** из [RFC 5280, Internet X.509 Public Key Infrastructure Certificate и Профиль списка отзыва сертификатов (CRL)] (https://tools.ietf.org/html/rfc5280). – jww

+0

Вы также можете посмотреть [RFC 2986, Спецификация синтаксиса запроса на сертификацию] (https://tools.ietf.org/html/rfc2986) и [Draft Gutmann SCEP, Простой протокол регистрации сертификатов] (http: //tools.ietf. орг/html/проект-Гутман-РДЕ-03). – jww

+0

Извините, если мой вопрос был не ясен. Я использую некоторые функции OpenSSL, и поэтому я пометил его. Это первый раз, когда я использую этот форум, поэтому при необходимости я могу удалить тег, чтобы у нас была лучшая среда. Теперь я пытаюсь создать один файл CSR. Поэтому я добавляю все компоненты (версию, тему, тип шифрования и т. Д.), Чтобы сделать это. Последним компонентом этой CSR является подпись. Но я не знаю, что мне нужно подписать, чтобы иметь эту последнюю часть в моем файле DER. Я проведу RFC2986, чтобы лучше понять CSR. Ваши ответы очень полезны! –

ответ

2

Под «внедренным» вы подразумеваете, что вы их закодировали самостоятельно, или вы выбрали фрагменты из источника OpenSSL? В последнем случае я предполагаю, что у вас есть полный источник, доступный для просмотра, даже если он не скомпилирован на вашем ограниченном устройстве.

CSRs, как (X.509) и сертификаты CRLs, используют общую структуру верхнего уровня:

SEQUENCE 
    body (itself a SEQUENCE of various things depending on what this thing is) 
    AlgorithmIdentifier = SEQUENCE { OID, NULL } identifying the algorithm 
    BIT STRING containing signature in algorithm-dependent format 

Обратите внимание, что похолодевший и подпись отдельные элементы и вне последовательности в организме, хотя внутри ПОСЛЕДОВАТЕЛЬНОСТЬ ПЕРВОГО уровня.

Для CSR это выложено в PKCS # 10, более стабильно доступно как RFC2986; смотри раздел 4.

В частности, я надеюсь, что ваши «4.- Тип шифрования» на самом деле является AlgorithmIdentifier для алгоритма ОткрытыйКлюч который для RSA по историческим причинам является OID rsaEncryption = 1.2.840.113549.1.1.1, даже если RSA используется для подписи, как а также шифрование и «5.-Modulus & Exponent» - это действительно BIT STRING, содержащая DER-кодирование открытого ключа PKCS # 1, который является SEQUENCE, содержащим эти два INTEGER, и что 4 и 5 сгруппированы в SEQUENCE для формирования SubjectPublicKeyInfo ,

Как описано в разделе 4.2, «тело» (certRequestInfo) кодируется DER, и эта кодировка подписывается вашим закрытым ключом - для RSA на практике с использованием PKCS1-v1_5, хотя существуют другие схемы подписки RSA , Эта схема подписи создает строку октета (в общем смысле, а не тип ASN.1), которая используется как значение в BIT STRING.

В зависимости от того, какие примитивы вы используете, помните, что PKCS1-v1_5 требует, чтобы вы передавали сообщение (здесь certRequestInfo), кодируете этот хэш в ASN.1 SEQUENCE с помощью AlgId для хэша, pad, который ASN.1 с 01 FF ... 00 и modexp (OS2I of) результат с d.В OpenSSL EVP_DigestSign* выполняет все 4 шага, EVP_PKEY_sign* делает последние 3, а RSA_private_encrypt [sic] делает последние 2, то есть НЕ делает ASN.1 (и, необязательно, не делает дополнение).


Ваш комментарий слишком неопределенны для меня, чтобы быть ясно, что вы делаете, так вот ДЕЙСТВИТЕЛЬНО Пример:

$ openssl req -newkey rsa:2048 -nodes -keyout SO39842014.key \ 
    -subj '/CN=example.com/C=AU/O=Widgits Pty' -outform d -out SO39842014.req 
Generating a 2048 bit RSA private key 
.............+++ 
..+++ 
writing new private key to 'SO39842014.key' 
----- 
$ # -nodes to simplify example; real keys should be secured! 
$ openssl rsa -in SO39842014.key -pubout -out SO39842014.pub 
writing RSA key 
$ 
$ xxd SO39842014.req 
0000000: 3082 027e 3082 0166 0201 0030 3931 1430 0..~0..f...091.0 
0000010: 1206 0355 0403 0c0b 6578 616d 706c 652e ...U....example. 
0000020: 636f 6d31 0b30 0906 0355 0406 1302 4155 com1.0...U....AU 
0000030: 3114 3012 0603 5504 0a0c 0b57 6964 6769 1.0...U....Widgi 
0000040: 7473 2050 7479 3082 0122 300d 0609 2a86 ts Pty0.."0...*. 
0000050: 4886 f70d 0101 0105 0003 8201 0f00 3082 H.............0. 
0000060: 010a 0282 0101 00fa 06d2 819f be88 270e ..............'. 
0000070: 5cc8 8938 aa2d c87c 01e5 bbbd d4c7 e9b6 \..8.-.|........ 
0000080: 1401 65b3 adf1 52fd 671b 7fa4 6a26 7f36 ..e...R.g...j&.6 
0000090: ca1c aec5 877e 2954 1541 0a88 366a 6b52 .....~)T.A..6jkR 
00000a0: b3f1 4303 3848 5b05 2b58 e299 c0fd 5a65 ..C.8H[.+X....Ze 
00000b0: 4748 4d43 9e5a 26b3 382e 9600 3ce3 4eb6 GHMC.Z&.8...<.N. 
00000c0: 09a8 8554 25b4 3ad3 abee 49c8 d15d 27c5 ...T%.:...I..]'. 
00000d0: aa9e ff56 f511 a1b6 daaa d484 86ce c0fd ...V............ 
00000e0: e4bf 7435 69ed 2806 2adb 9674 a06c 21d9 ..t5i.(.*..t.l!. 
00000f0: c64c 0741 88d1 2f4a d2ec b7ec e24c 2cad .L.A../J.....L,. 
0000100: 0dc4 8deb 7fc6 3c9d 3eee a5f6 4aeb 9bd0 ......<.>...J... 
0000110: b2b8 0e48 5baf d272 8628 1d79 a05d e632 ...H[..r.(.y.].2 
0000120: befa 9f3e eac5 fafb eae1 a0c9 c9a7 3a69 ...>..........:i 
0000130: 4ec5 733e 63fc 47d8 bbcc 1c07 1f22 e190 N.s>c.G......".. 
0000140: 1ac7 e6d4 f71f 9c4b 1d1b 6cb9 303a b05a .......K..l.0:.Z 
0000150: 4d4f c1e1 8c0e 2b09 5f39 2058 89f7 b2ee MO....+._9 X.... 
0000160: 9e2c 6b5d 6b2c 2d02 0301 0001 a000 300d .,k]k,-.......0. 
0000170: 0609 2a86 4886 f70d 0101 0505 0003 8201 ..*.H........... 
0000180: 0100 6a7e 8afc d5b1 f55c a824 3516 44f2 ..j~.....\.$5.D. 
0000190: ec60 d081 2334 eaae 6d8d 8f79 7e18 bbea .`..#4..m..y~... 
00001a0: c932 bd07 1dc0 67ad 636b b552 619e 9d7f .2....g.ck.Ra... 
00001b0: 5291 3829 0649 e64a 07b6 d659 e181 127e R.8).I.J...Y...~ 
00001c0: a56f 3ab9 7dad 9f53 adf9 7c86 3035 ae1c .o:.}..S..|.05.. 
00001d0: 9b20 7509 3618 c71e 8f47 98da 4f03 c377 . u.6....G..O..w 
00001e0: 52a7 c56e 0a58 265b be81 d263 a9f3 e2c8 R..n.X&[...c.... 
00001f0: d465 fab6 46a2 269a d649 be08 5857 4a40 .e..F.&[email protected] 
0000200: 4cd0 0ddf 17a3 a605 c2a3 a2ae 1c1f c22a L..............* 
0000210: 4aa5 1e1b 6b8a dfd4 708c 55f1 05c5 8309 J...k...p.U..... 
0000220: fd62 78d4 e650 367c bf91 2c18 3ccb f6f4 .bx..P6|..,.<... 
0000230: c52f 0770 3a44 9558 709f ebba 8878 3fce ./.p:D.Xp....x?. 
0000240: 4588 a7bb d605 8c46 c80c 3b11 8420 c8bd E......F..;.. .. 
0000250: 623c 8205 7d25 1588 017f 2e1b bf09 881f b<..}%.......... 
0000260: a56b 5d0f 617a 9914 611d 2336 8335 2f74 .k].az..a.#6.5/t 
0000270: 42f9 7188 4b67 7c65 5d83 bc51 52af 124a B.q.Kg|e]..QR..J 
0000280: d426          .& 

Он состоит из внешней ПОСЛЕДОВАТЕЛЬНОСТИ тег & длины, то TBS или корпус (certificationRequestInfo) в 4-х до 0x16E, который это ДЕР кодирование:

$ dd if=SO39842014.req bs=1 skip=4 count=$((0x16E-4)) 2>dev/null \ 
    | openssl asn1parse -inform d -i 
    0:d=0 hl=4 l= 358 cons: SEQUENCE 
    4:d=1 hl=2 l= 1 prim: INTEGER   :00 
    7:d=1 hl=2 l= 57 cons: SEQUENCE 
    9:d=2 hl=2 l= 20 cons: SET 
    11:d=3 hl=2 l= 18 cons: SEQUENCE 
    13:d=4 hl=2 l= 3 prim:  OBJECT   :commonName 
    18:d=4 hl=2 l= 11 prim:  UTF8STRING  :example.com 
    31:d=2 hl=2 l= 11 cons: SET 
    33:d=3 hl=2 l= 9 cons: SEQUENCE 
    35:d=4 hl=2 l= 3 prim:  OBJECT   :countryName 
    40:d=4 hl=2 l= 2 prim:  PRINTABLESTRING :AU 
    44:d=2 hl=2 l= 20 cons: SET 
    46:d=3 hl=2 l= 18 cons: SEQUENCE 
    48:d=4 hl=2 l= 3 prim:  OBJECT   :organizationName 
    53:d=4 hl=2 l= 11 prim:  UTF8STRING  :Widgits Pty 
    66:d=1 hl=4 l= 290 cons: SEQUENCE 
    70:d=2 hl=2 l= 13 cons: SEQUENCE 
    72:d=3 hl=2 l= 9 prim: OBJECT   :rsaEncryption 
    83:d=3 hl=2 l= 0 prim: NULL 
    85:d=2 hl=4 l= 271 prim: BIT STRING 
    360:d=1 hl=2 l= 0 cons: cont [ 0 ] 

с последующим похолодевшим для подписи (так называемого «внешнего» похолодевший) при 0x16E до 0x17D:

$ dd if=SO39842014.req bs=1 skip=$((0x16E)) count=$((0xF)) 2>/dev/null \ 
    | openssl asn1parse -inform d -i 
    0:d=0 hl=2 l= 13 cons: SEQUENCE 
    2:d=1 hl=2 l= 9 prim: OBJECT   :sha1WithRSAEncryption 
    13:d=1 hl=2 l= 0 prim: NULL 

, за которым следует BIT STRING, содержащая значение подписи от 0x182 до 0x282. Это может быть проверено подписью TBS:

$ dd if=SO39842014.req bs=1 skip=$((0x282)) of=SO39842014.sig 2>/dev/null 
$ dd if=SO39842014.req bs=1 skip=4 count=$((0x16E-4)) 2>/dev/null \ 
    | openssl dgst -sha1 -verify SO39842014.pub -signature SO39842014.sig 
Verified OK 

или после PKCS1-v1_5 подписи является детерминированным мы можем воссоздать ту же подпись:

$ dd if=SO39842014.req bs=1 skip=4 count=$((0x16E-4)) 2>/dev/null \ 
| openssl dgst -sha1 -sign SO39842014.key | xxd 
0000000: 6a7e 8afc d5b1 f55c a824 3516 44f2 ec60 j~.....\.$5.D..` 
0000010: d081 2334 eaae 6d8d 8f79 7e18 bbea c932 ..#4..m..y~....2 
0000020: bd07 1dc0 67ad 636b b552 619e 9d7f 5291 ....g.ck.Ra...R. 
0000030: 3829 0649 e64a 07b6 d659 e181 127e a56f 8).I.J...Y...~.o 
0000040: 3ab9 7dad 9f53 adf9 7c86 3035 ae1c 9b20 :.}..S..|.05... 
0000050: 7509 3618 c71e 8f47 98da 4f03 c377 52a7 u.6....G..O..wR. 
0000060: c56e 0a58 265b be81 d263 a9f3 e2c8 d465 .n.X&[...c.....e 
0000070: fab6 46a2 269a d649 be08 5857 4a40 4cd0 ..F.&[email protected] 
0000080: 0ddf 17a3 a605 c2a3 a2ae 1c1f c22a 4aa5 .............*J. 
0000090: 1e1b 6b8a dfd4 708c 55f1 05c5 8309 fd62 ..k...p.U......b 
00000a0: 78d4 e650 367c bf91 2c18 3ccb f6f4 c52f x..P6|..,.<..../ 
00000b0: 0770 3a44 9558 709f ebba 8878 3fce 4588 .p:D.Xp....x?.E. 
00000c0: a7bb d605 8c46 c80c 3b11 8420 c8bd 623c .....F..;.. ..b< 
00000d0: 8205 7d25 1588 017f 2e1b bf09 881f a56b ..}%...........k 
00000e0: 5d0f 617a 9914 611d 2336 8335 2f74 42f9 ].az..a.#6.5/tB. 
00000f0: 7188 4b67 7c65 5d83 bc51 52af 124a d426 q.Kg|e]..QR..J.& 

Наконец, так как это (как и большинство) RSA подписи позволяет «восстановление» (иногда ошибочно называют «расшифровать с помощью открытого ключа»), мы можем взглянуть на значение на самом деле ввода в modexp-D:

$ openssl rsautl -in SO39842014.sig -verify -inkey SO39842014.pub -pubin -raw |xxd 
0000000: 0001 ffff ffff ffff ffff ffff ffff ffff ................ 
0000010: ffff ffff ffff ffff ffff ffff ffff ffff ................ 
0000020: ffff ffff ffff ffff ffff ffff ffff ffff ................ 
0000030: ffff ffff ffff ffff ffff ffff ffff ffff ................ 
0000040: ffff ffff ffff ffff ffff ffff ffff ffff ................ 
0000050: ffff ffff ffff ffff ffff ffff ffff ffff ................ 
0000060: ffff ffff ffff ffff ffff ffff ffff ffff ................ 
0000070: ffff ffff ffff ffff ffff ffff ffff ffff ................ 
0000080: ffff ffff ffff ffff ffff ffff ffff ffff ................ 
0000090: ffff ffff ffff ffff ffff ffff ffff ffff ................ 
00000a0: ffff ffff ffff ffff ffff ffff ffff ffff ................ 
00000b0: ffff ffff ffff ffff ffff ffff ffff ffff ................ 
00000c0: ffff ffff ffff ffff ffff ffff ffff ffff ................ 
00000d0: ffff ffff ffff ffff ffff ffff 0030 2130 .............0!0 
00000e0: 0906 052b 0e03 021a 0500 0414 e577 fca2 ...+.........w.. 
00000f0: 2372 a03a a4fe a0d1 485d 7f71 1321 37c4 #r.:....H].q.!7. 

и увидеть это состоит из типа 01 заполнения последовательности ASN.1, содержащей AlgId для SHA1, и OCTET STRING, содержащей фактический хеш:

$ if=SO39842014.req bs=1 skip=4 count=$((0x16E-4)) 2>/dev/null \ 
    | openssl dgst -sha1 
(stdin)= e577fca22372a03aa4fea0d1485d7f71132137c4 
+0

Большое вам спасибо за ответ. Да, я сам программирую функции. Что касается «4.- Тип шифрования», этот алгоритм Идентификатор может быть извлечен из ключа RSA, который я сгенерировал, не может быть? Я рассмотрю RFC2986, чтобы выяснить, что мне нужно подписать. До этого момента у меня есть необходимая информация для создания CSR (в DER). Я дам вам знать мои результаты. Спасибо! –

+0

@ Mr.Bogus: зависит от того, что вы подразумеваете под сгенерированным.'RSA_generate_key [_ex]' создает только номера RSA (n = pq, e, d, dmp1, dmq1, qinv). 'EVP_PKEY_keygen' добавляет внутренний тег для RSA, но это не ASN.1 AlgId. Если вы кодируете 'i2d_ [RSA_] PUBKEY *' или 'PEM_write * [RSA_] PUBKEY' или кодируете' X509' или 'X509_REQ', который содержит« EVP_PKEY »типа RSA, они преобразуют внутренний тег в AlgId, в конечном счете используя 'OBJ_nid2obj (EVP_PKEY_RSA)' в 'rsa_pub_encode' в' crypto/rsa/rsa_ameth.c', где 'EVP_PKEY_RSA'' # define''d как 'NID_rsaEncryption', который является NID для OID, который я дал. ... –

+0

... Также, чтобы быть понятным, это AlgId для ключа _in SPKI_. AlgId для подписи должен быть «sha1WithRSA» или аналогичным, а значение AlgId в значении PKCS1-v1_5 должно быть просто «sha1» или аналогичным. –

 Смежные вопросы

  • Нет связанных вопросов^_^