18.03.2005 12:13:57ЭЦП + комментарий + идентификатор ресурса Ответов: 27
Дробязко Алексей
Добрый день! Никак не могу прикрутить к ЭЦП коментарий и индентификатор ресурса, как сделано в КриптоАРМе...Помогите пожалуйста.
Добавлять к ЭЦП время я умею:
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;

 
Ответы:
18.03.2005 13:47:23Kirill Sobolev
А что именно и в каком месте не прикручивается? :)
18.03.2005 14:01:24Дробязко Алексей
Во-первых, если для времени в функции 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;
18.03.2005 14:27:45Kirill Sobolev
В КриптоАРМе они лежат в простой BMPString с OID 1.3.6.1.4.1.311.2.1.120.
Можете сами посмотреть подпись допустим certutil и убедиться :)
18.03.2005 14:59:06Дробязко Алексей
Чтобы добавить к подписи врямя и некоторый комментарий, делаю следующее:

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 встречен неожиданный конец данных" и получить аттрибуты, как и другую информация по подписи не получается.
18.03.2005 15:25:20Kirill Sobolev
1)Получается ca[1].rgValue=ca[2].rgValue?
2)В С массивы индексируются с 0, в дельфи не так?
18.03.2005 15:39:26Дробязко Алексей
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;
----------------------
В чем же проблема(кроме моих корявых рук, конечно :)))?
18.03.2005 15:45:35Kirill Sobolev
Вот это я и хотел уточнить - какой значение будет у ((CRYPT_ATTR_BLOB)ca[1].rgValue).pbData после присваивания
g := ’Some comment’;
cablob[1].cbData := length( g );
cablob[1].pbData := PBYTE(g);
18.03.2005 16:16:19Дробязко Алексей
:)) В((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 встречен...", нельзя получить сертификат пользователя.
18.03.2005 16:28:38Kirill Sobolev
Значит еще где-то проблема.
Без результатов того, что получается, сказать сложно...
Поробуйте еще отдельно добавить время и отдельно комментарий - будет это работать?
21.03.2005 11:46:20Дробязко Алексей
Добрый день, Кирил. Вот вернулся опять к решению этой проблемы. Пробовал добавлять к сообщению:
- только время (успешно)
- только комментарий (ошибка)
- врямя + коментарий (ошибка)

!!! Но вот, когда я попробывал присоединить только коментарий с значением строки комментария равным зашифрованому времени, то это прошло успешно: вот что я сделал:

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 я действительно увидел, что значение комментария храниться незашифрованным.
21.03.2005 12:17:35Kirill Sobolev
Его не шифровать надо а кодировать в BMPString. Кстати, комментарий с иденификатором лежат как SEQUENCE
21.03.2005 12:17:41Kirill Sobolev
Его не шифровать надо а кодировать в BMPString. Кстати, комментарий с иденификатором лежат как SEQUENCE
21.03.2005 15:00:46Дробязко Алексей
Я с помощью Вашего КриптоАРМа поставил подпись и добавил комментарий "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.
В чем же тут дело?
21.03.2005 15:01:01Дробязко Алексей
Я с помощью Вашего КриптоАРМа поставил подпись и добавил комментарий "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.
В чем же тут дело?
21.03.2005 15:29:54Дробязко Алексей
Не подскажете еще, какое все-таки имя у константы ’1.3.6.1.4.1.311.2.1.120’?
07.08.2007 18:32:41Гидеон
А вот интересно... КриптоАРМ укладывает комментарий и URI в autenticated atributes... Причём, требований к обязательности этого я не нашёл. А если записывать комментарий и URI в unautenticated atributes, с OIDом SystemComment-а, чему это противоречит?
08.08.2007 9:20:16Kirill Sobolev
Ничему не противоречит. Просто на неподписанные атрибуты при проверке подписи можно не обращать внимание.
08.08.2007 13:02:17Гидеон
Тогда более общий вопрос - чем обосновано создание собственного OID-а и включение комментария в подписанные атрибуты подписи? Про URI я вообще не говорю...
Насколько я понимаю, формальных требований (включая наше законодательство) по аутентифицированию комментария нет. У Микрософта комментарий предполагается размещать именно в неподписанных атрибутах, для этого даже формат предусмотрен. Зачем изобретать собственный OID, да ещё и без friendly name, ради чего? Ведь ясно, что возникнет проблема расчитывания подписи - проверяющей стороне надо знать, чем создана подпись - КриптоАРМом или чем-то другим... Иначе непонятно, где искать комментарий. Врядли это сделано для целенаправленной несовместимости с другими средствами формирования ЭЦП... Значит должны быть объяснения этому...
08.08.2007 13:54:49Kirill Sobolev
Наверняка есть.
Попробуйте этот вопрос задать на http://www.digt.ru/support/forum/viewforum.php?f=22&sid=c78b9399d9aff8fc85f37a322b985f42
08.08.2007 15:07:09Гидеон
Попробую...
Просто странно - есть вполне себе стандартный X509_ANY_STRING или PKCS_CONTENT_INFO...
Зачем плодить несовместимые сущности? Ведь, собственно говоря, без КриптоАРМа в общем случае такой атрибут и расчитать толком нельзя... Хорошо, хоть формат строки оставили читаемым... ;)
08.08.2007 15:22:52Andrey Nechaev (www.digt.ru)
Использование собственного OIDа было придумано на начальном этапе развития КриптоАРМ. Но даже сейчас я не вижу лучшего решения для поддержки новых специфических атрибутов подписи. Проблемы с "расчитыванием подписи" быть не должно - все атрибуты, которые программе не известны, просто не должны декодироваться (по аналогии с certutil). А в подписанный атрибут эти данные кладутся по той причине, чтобы не было возможности их подредактировать - если кто-либо их изменит, то ЭЦП станет математически некорректной.
08.08.2007 16:01:16Гидеон
Андрей, добрый день.
Понятно, что неизвестный OID просто будет пропущен при проверке. Но если он потенциально пропускается (по большому счёту этот атрибут корректно читается только КриптоАРМом), значит, строго говоря, он не будет учитываться системой подтверждения валидности подписи удостоверяющего центра. А если так - то зачем так охранять его целостность? На значимость ЭЦП он всё равно не повлияет...
08.08.2007 16:15:50Гидеон
Да и если "подправить" неподписанный атрибут, подпись всё равно разрушается...
08.08.2007 16:43:36Andrey Nechaev (www.digt.ru)
Почему подпись разрушается, если подправить неподписанный атрибут? А относительно сохранения целостности предложу пример, может и не совсем удачный, с собственноручной подписью: начальник пишет (от руки): "Разрешить" и ставит подпись. На бумаге эту запись достаточно сложно изменить на "Отказать", а в случае неподписанного атрибута - проще простого.
08.08.2007 17:13:13Гидеон
Андрей, я говорю о подписи, структуре PKCS#7, а не о сигнатуре. Но я Вас понял, действительно, комментарий криптографически не защищён.
Поэтому коротко сформулирую мои вопросы:
1. Зачем криптографически защищать комментарий, если системы валидации ЭЦП комментарий (как условия установки подписи), при подтверждении значимости ЭЦП, не рассматривают? Задел на будущее?
2. Зачем использовать для комментария нестандартный OID, если есть X509_ANY_STRING, читаемый всеми?
08.08.2007 17:55:56Andrey Nechaev (www.digt.ru)
1. Комментарий и идентификатор ресурса был поддержан по просьбе одного из крупных закачиков, который просил также чтобы они были подписанными. Если в Вашей системе возникают проблемы с проверкой этих полей, то просто не используйте их при создании ЭЦП.
2. Не совсем понял, как "нестандартный OID" связан с типом кодирования X509_ANY_STRING. Но в любом случае - тогда это было реализовано не совсем грамотно, а теперь не хочется изменять из-за потери совместимости.
08.08.2007 18:43:57Гидеон
Спасибо, Андрей, всё понятно. То есть этот момент заказной.

ЗЫ. По поводу X509_ANY_STRING - имел в виду этим создать юникодную строку, а потом по OID-у RSA_Data уложить в подписываемые атрибуты...