| ||||
| ||||
Добрый день! Никак не могу прикрутить к ЭЦП коментарий и индентификатор ресурса, как сделано в КриптоАРМе...Помогите пожалуйста. Добавлять к ЭЦП время я умею: CryptEncodeObject(TYPE_DER, szOID_RSA_signingTime, @fileTime, NIL, cbAuth); CryptEncodeObject(TYPE_DER, szOID_RSA_signingTime, @fileTime, pbAuth, cbAuth); cablob[1].cbData := cbAuth; cablob[1].pbData := pbAuth; ca[1].pszObjId := szOID_RSA_signingTime; ca[1].cValue := 1; ca[1].rgValue := @cablob; | ||||
Ответы: | ||||
| ||||
А что именно и в каком месте не прикручивается? :) | ||||
| ||||
Во-первых, если для времени в функции CryptEncodeObject используется szOID_RSA_signingTime, то для комментария и индентификатора ресурса, я идентификаторов не нашел. Во-вторых, не могу же без кодирования коментария записать его в массив аттрибутов, т.е. comment := ’Некоторый комментарий’; cablob[1].cbData := length(comment); cablob[1].pbData := pbyte(comment); ca[2].pszObjId := ????; ca[2].cValue := 1; ca[2].rgValue := @cablob; | ||||
| ||||
В КриптоАРМе они лежат в простой BMPString с OID 1.3.6.1.4.1.311.2.1.120. Можете сами посмотреть подпись допустим certutil и убедиться :) | ||||
| ||||
Чтобы добавить к подписи врямя и некоторый комментарий, делаю следующее: CryptEncodeObject(TYPE_DER, szOID_RSA_signingTime, @fileTime, NIL, cbAuth); CryptEncodeObject(TYPE_DER, szOID_RSA_signingTime, @fileTime, pbAuth, cbAuth); cablob[1].cbData := cbAuth; cablob[1].pbData := pbAuth; ca[1].pszObjId := szOID_RSA_signingTime; ca[1].cValue := 1; ca[1].rgValue := @cablob; g := ’Some comment’; cablob[1].cbData := length( g ); cablob[1].pbData := PBYTE(g); ca[2].pszObjId := ’1.3.6.1.4.1.311.2.1.120’; ca[2].cValue := 1; ca[2].rgValue := @cablob; SignerEncodeInfo.cbSize := sizeof(CMSG_SIGNER_ENCODE_INFO); SignerEncodeInfo.pCertInfo := pUserCert^.pCertInfo; SignerEncodeInfo.hCryptProv := hProv; SignerEncodeInfo.dwKeySpec := keytype; SignerEncodeInfo.HashAlgorithm := HashAlgorithm; SignerEncodeInfo.pvHashAuxInfo := NIL; SignerEncodeInfo.cAuthAttr := 2; SignerEncodeInfo.rgAuthAttr := @ca; и т.д. ! Но когда проверяю подпись (просматриваю аттрибуты) на функции CryptMsgGetParam(hMsg, CMSG_SIGNER_AUTH_ATTR_PARAM,signerIndex,NIL,@authAttr_len); возникает ошибка "В ASN1 встречен неожиданный конец данных" и получить аттрибуты, как и другую информация по подписи не получается. | ||||
| ||||
1)Получается ca[1].rgValue=ca[2].rgValue? 2)В С массивы индексируются с 0, в дельфи не так? | ||||
| ||||
1)Нет, тут все нормально. Я же присвоил cablob[1].cbData := length( g ); cablob[1].pbData := PBYTE(g); Т.е. у него теперь новые значения 2)В Делфи я обьявил cablob : array[1..1] of CRYPT_ATTR_BLOB; ca : array[1..2] of CRYPT_ATTRIBUTE; ---------------------- В чем же проблема(кроме моих корявых рук, конечно :)))? | ||||
| ||||
Вот это я и хотел уточнить - какой значение будет у ((CRYPT_ATTR_BLOB)ca[1].rgValue).pbData после присваивания g := ’Some comment’; cablob[1].cbData := length( g ); cablob[1].pbData := PBYTE(g); | ||||
| ||||
:)) В((CRYPT_ATTR_BLOB)ca[1].rgValue).pbData будет указатель на ’Some comment’. Я это пофиксил ввидя новый массив вablob.......... cablob : array[1..1] of CRYPT_ATTR_BLOB; dablob : array[1..1] of CRYPT_ATTR_BLOB; ca : array[1..2] of CRYPT_ATTRIBUTE; С учетом изменений... CryptEncodeObject(TYPE_DER, szOID_RSA_signingTime, @fileTime, NIL, cbAuth); CryptEncodeObject(TYPE_DER, szOID_RSA_signingTime, @fileTime, pbAuth, cbAuth); cablob[1].cbData := cbAuth; cablob[1].pbData := pbAuth; ca[1].pszObjId := szOID_RSA_signingTime; ca[1].cValue := 1; ca[1].rgValue := @cablob; g := ’Some comment’; dablob[1].cbData := length( g ); dablob[1].pbData := PBYTE(g); ca[2].pszObjId := ’1.3.6.1.4.1.311.2.1.120’; ca[2].cValue := 1; ca[2].rgValue := @cablob; ! Но проблема не решилась. Вообщем-то процедура подписи осуществляется корректно, а вот проверка подписи "падает", т.е. при получении аттрибутов подписи появляется таже ошибка "В ASN1 встречен...", нельзя получить сертификат пользователя. | ||||
| ||||
Значит еще где-то проблема. Без результатов того, что получается, сказать сложно... Поробуйте еще отдельно добавить время и отдельно комментарий - будет это работать? | ||||
| ||||
Добрый день, Кирил. Вот вернулся опять к решению этой проблемы. Пробовал добавлять к сообщению: - только время (успешно) - только комментарий (ошибка) - врямя + коментарий (ошибка) !!! Но вот, когда я попробывал присоединить только коментарий с значением строки комментария равным зашифрованому времени, то это прошло успешно: вот что я сделал: CryptEncodeObject(TYPE_DER, szOID_RSA_signingTime, @fileTime, NIL, cbAuth); CryptEncodeObject(TYPE_DER, szOID_RSA_signingTime, @fileTime, pbAuth, cbAuth); dablob[1].cbData := cbAuth; dablob[1].pbData := pbAuth; ca[1].pszObjId := ’1.3.6.1.4.1.311.2.1.120’; ca[1].cValue := 1; ca[1].rgValue := @dablob; Может все-таки коментарий необходимо шифровать? Хотя с помощью certutil я действительно увидел, что значение комментария храниться незашифрованным. | ||||
| ||||
Его не шифровать надо а кодировать в BMPString. Кстати, комментарий с иденификатором лежат как SEQUENCE | ||||
| ||||
Его не шифровать надо а кодировать в BMPString. Кстати, комментарий с иденификатором лежат как SEQUENCE | ||||
| ||||
Я с помощью Вашего КриптоАРМа поставил подпись и добавил комментарий "TEST COMMENT". Вот дамп файла с подписью: PKCS7 Message Authenticated Attributes: 4 attributes: Attribute[0]: 1.2.840.113549.1.9.3 (Content Type) Value[0][0]: Unknown Attribute type 0000 06 09 2a 86 48 86 f7 0d 01 07 01 ..*.H...... Attribute[1]: 1.2.840.113549.1.9.5 (Signing Time) Value[1][0]: Unknown Attribute type 0000 17 0d 30 35 30 33 32 31 31 31 35 30 35 31 5a ..050321115051Z Attribute[2]: 1.2.840.113549.1.9.4 (Message Digest) Value[2][0]: Unknown Attribute type 0000 04 10 f2 02 53 fc 3a 3d 79 63 6a 67 3b 4c 08 b9 ....S.:=ycjg;L.. 0010 61 d9 a. Attribute[3]: 1.3.6.1.4.1.311.2.1.120 Value[3][0]: Unknown Attribute type 0000 30 1c 1e 18 00 54 00 45 00 53 00 54 00 20 00 43 0....T.E.S.T. .C 0010 00 4f 00 4d 00 4d 00 45 00 4e 00 54 1e 00 .O.M.M.E.N.T.. Получается, что все-таки строка с комментарием как-то кодируется, потому что ей предшествуют символы с кодами 30 1c 1e 18 00 и замыкают ее символы 1e 00. В чем же тут дело? | ||||
| ||||
Я с помощью Вашего КриптоАРМа поставил подпись и добавил комментарий "TEST COMMENT". Вот дамп файла с подписью: PKCS7 Message Authenticated Attributes: 4 attributes: Attribute[0]: 1.2.840.113549.1.9.3 (Content Type) Value[0][0]: Unknown Attribute type 0000 06 09 2a 86 48 86 f7 0d 01 07 01 ..*.H...... Attribute[1]: 1.2.840.113549.1.9.5 (Signing Time) Value[1][0]: Unknown Attribute type 0000 17 0d 30 35 30 33 32 31 31 31 35 30 35 31 5a ..050321115051Z Attribute[2]: 1.2.840.113549.1.9.4 (Message Digest) Value[2][0]: Unknown Attribute type 0000 04 10 f2 02 53 fc 3a 3d 79 63 6a 67 3b 4c 08 b9 ....S.:=ycjg;L.. 0010 61 d9 a. Attribute[3]: 1.3.6.1.4.1.311.2.1.120 Value[3][0]: Unknown Attribute type 0000 30 1c 1e 18 00 54 00 45 00 53 00 54 00 20 00 43 0....T.E.S.T. .C 0010 00 4f 00 4d 00 4d 00 45 00 4e 00 54 1e 00 .O.M.M.E.N.T.. Получается, что все-таки строка с комментарием как-то кодируется, потому что ей предшествуют символы с кодами 30 1c 1e 18 00 и замыкают ее символы 1e 00. В чем же тут дело? | ||||
| ||||
Не подскажете еще, какое все-таки имя у константы ’1.3.6.1.4.1.311.2.1.120’? | ||||
| ||||
А вот интересно... КриптоАРМ укладывает комментарий и URI в autenticated atributes... Причём, требований к обязательности этого я не нашёл. А если записывать комментарий и URI в unautenticated atributes, с OIDом SystemComment-а, чему это противоречит? | ||||
| ||||
Ничему не противоречит. Просто на неподписанные атрибуты при проверке подписи можно не обращать внимание. | ||||
| ||||
Тогда более общий вопрос - чем обосновано создание собственного OID-а и включение комментария в подписанные атрибуты подписи? Про URI я вообще не говорю... Насколько я понимаю, формальных требований (включая наше законодательство) по аутентифицированию комментария нет. У Микрософта комментарий предполагается размещать именно в неподписанных атрибутах, для этого даже формат предусмотрен. Зачем изобретать собственный OID, да ещё и без friendly name, ради чего? Ведь ясно, что возникнет проблема расчитывания подписи - проверяющей стороне надо знать, чем создана подпись - КриптоАРМом или чем-то другим... Иначе непонятно, где искать комментарий. Врядли это сделано для целенаправленной несовместимости с другими средствами формирования ЭЦП... Значит должны быть объяснения этому... | ||||
| ||||
Наверняка есть. Попробуйте этот вопрос задать на http://www.digt.ru/support/forum/viewforum.php?f=22&sid=c78b9399d9aff8fc85f37a322b985f42 | ||||
| ||||
Попробую... Просто странно - есть вполне себе стандартный X509_ANY_STRING или PKCS_CONTENT_INFO... Зачем плодить несовместимые сущности? Ведь, собственно говоря, без КриптоАРМа в общем случае такой атрибут и расчитать толком нельзя... Хорошо, хоть формат строки оставили читаемым... ;) | ||||
| ||||
Использование собственного OIDа было придумано на начальном этапе развития КриптоАРМ. Но даже сейчас я не вижу лучшего решения для поддержки новых специфических атрибутов подписи. Проблемы с "расчитыванием подписи" быть не должно - все атрибуты, которые программе не известны, просто не должны декодироваться (по аналогии с certutil). А в подписанный атрибут эти данные кладутся по той причине, чтобы не было возможности их подредактировать - если кто-либо их изменит, то ЭЦП станет математически некорректной. | ||||
| ||||
Андрей, добрый день. Понятно, что неизвестный OID просто будет пропущен при проверке. Но если он потенциально пропускается (по большому счёту этот атрибут корректно читается только КриптоАРМом), значит, строго говоря, он не будет учитываться системой подтверждения валидности подписи удостоверяющего центра. А если так - то зачем так охранять его целостность? На значимость ЭЦП он всё равно не повлияет... | ||||
| ||||
Да и если "подправить" неподписанный атрибут, подпись всё равно разрушается... | ||||
| ||||
Почему подпись разрушается, если подправить неподписанный атрибут? А относительно сохранения целостности предложу пример, может и не совсем удачный, с собственноручной подписью: начальник пишет (от руки): "Разрешить" и ставит подпись. На бумаге эту запись достаточно сложно изменить на "Отказать", а в случае неподписанного атрибута - проще простого. | ||||
| ||||
Андрей, я говорю о подписи, структуре PKCS#7, а не о сигнатуре. Но я Вас понял, действительно, комментарий криптографически не защищён. Поэтому коротко сформулирую мои вопросы: 1. Зачем криптографически защищать комментарий, если системы валидации ЭЦП комментарий (как условия установки подписи), при подтверждении значимости ЭЦП, не рассматривают? Задел на будущее? 2. Зачем использовать для комментария нестандартный OID, если есть X509_ANY_STRING, читаемый всеми? | ||||
| ||||
1. Комментарий и идентификатор ресурса был поддержан по просьбе одного из крупных закачиков, который просил также чтобы они были подписанными. Если в Вашей системе возникают проблемы с проверкой этих полей, то просто не используйте их при создании ЭЦП. 2. Не совсем понял, как "нестандартный OID" связан с типом кодирования X509_ANY_STRING. Но в любом случае - тогда это было реализовано не совсем грамотно, а теперь не хочется изменять из-за потери совместимости. | ||||
| ||||
Спасибо, Андрей, всё понятно. То есть этот момент заказной. ЗЫ. По поводу X509_ANY_STRING - имел в виду этим создать юникодную строку, а потом по OID-у RSA_Data уложить в подписываемые атрибуты... | ||||