14.07.2005 12:40:43Беда с SignMessage.Verify (capicom) Ответов: 14
Антон
Есть простенький почтовый клиент на c#. Из письма в кодировке base64 вытаскиваю Text и Signature. Текст перевожу в КОИ8 и все отлично читается. Далее (для проверки подписи) пишу :

SignMessage.Content = SigText;
SignMessage.Verify(Signature, true, CAPICOM.CAPICOM_SIGNED_DATA_VERIFY_FLAG.CAPICOM_VERIFY_SIGNATURE_ONLY);

Что только не пробовал. Подставлял туда и байты, и строку... Все напрасно.

Вопрос такой: подскажите, плиз, в чем тут дело? :)

Ошибки возникают разные: то Неизвестный криптографический алгоритм, то Неверное значение тэга ASN1

PS Сообщения получаем от системы РАПИДА. Подписываются библиотекой rapida.dll.
 
Ответы:
14.07.2005 17:58:12Kirill Sobolev
"Неизвестный криптографический алгоритм"
а КриптоПро CSP установлен? (если они конечно ГОСТом подписывают)
15.07.2005 10:41:12Антон
:)
Подписывают ГОСТом.
Установил CSP.
Ошибка изменилась на : Неправильное значение хэша...
:)
15.07.2005 10:53:04Kirill Sobolev
Проверяете подпись не того сообщения.
Вот тут аналогичная проблема
http://www.cryptopro.ru/CryptoPro/forum/myforum.asp?q=1588
+ еще надо учесть что текст в CAPICOM передается юникодный, а Rapida.dll подписывает ASCII, т.е. надо преобразовывать.
15.07.2005 11:42:53Антон
Спасибо.
"Проверяете подпись не того сообщения" - это исключено.
А вот RFC 2633 - это довольно интересно. Как я понял, В CAPICOM нужно засунуть текст (в юникоде) + к нему добавить шапку

Content-Type: text/plain
Content-Transfer-Encoding: base64

Но тогда шапка будет противоречить сообщению. Оно же уже не в base64... или же в CAPICOM нужно сначала сам текст перевести из base64 в koi (первоначальный текст в кои), а потом уже добавить шапку и все загнать в юников - capicom ?
15.07.2005 11:50:49Kirill Sobolev
Извиняюсь, неточно выразился.
"Не то" - значит "не то, что было изначально подписано". Как раз я имел ввиду, что заголовки тоже нужны.
В CAPICOM как раз нужно засунуть текст в ASCII (binary string). Причем именно тот, что пришел в письме - без всяких преобразований из base64
15.07.2005 12:02:53Антон
Встречено неверное значение тега ASN1 :)
Как я понял CAPICOM ругается, когда текст и подпись подсовываешь ему в byte[]. Но, мне кажется, я где-то читал у Вас на форуме, что эти errors можно пропустить... Это на самом деле так?
15.07.2005 12:10:49Kirill Sobolev
Так, по порядку.
Если в письме подпись отдельно от сообщения, то в Content записывается binary string, преобразованная из юникода, а в Verify передается юникодный base64
Если же подпись вместе с сообщением, то это все подсовывается в Verify
15.07.2005 12:41:06Антон
Подпись отдельно от сообщения, т.е.:

"в Content записывается binary string, преобразованная из юникода"

т.е. я пишу:

SigText=Encoding.ASCII.GetString(Encoding.Unicode.GetBytes(SigText));

=====================================

"в Verify передается юникодный base64"

а вот это я несовсем понял. Юникодный base64 - это вот так:

Signature=Encoding.Unicode.GetString(Convert.FromBase64String(Signature));

Ошибка : в asn1 встречен неожиданный конец данных...

Понимаю, что уже ничего не понимаю :)
15.07.2005 12:47:26Kirill Sobolev
Если в письме подпись отделно и в base64, то ее вообще никуда преобразовывать не надо.
15.07.2005 12:55:48Антон
:)
Ладно... Не буду Вас больше мучить...

Спасибо...
15.07.2005 15:34:47Антон
Возник еще вопрос:

а работает ли вообще метод Verify ?

Я что-то никак не пойму, почему нигде нет упоминания о сертификате?

Т.е. любой, кто перехватит письмо, сможет изменить содержимое, создать новый хеш и выслать нам. Хеш будет подходить к этому письму... и все дела.
Или же я где-то ошибся в использовании функции?

ПС Как только не подставлял хеш и текст. Всегда пишет : Неправильное значение хеша.
15.07.2005 17:43:37Kirill Sobolev
Работает :)
Информация о сертификате содержится в подписи.
Подпись - это не просто хеш, а зашифрованный секретным ключем отправителя. Т.е. если злоумышленник подменит подпись, у получателя не получится ее правильно расшифровать.
18.07.2005 10:13:43Антон
"Т.е. если злоумышленник подменит подпись, у получателя не получится ее правильно расшифровать."

Очень странно, ведь метод Verify никак не связан даже с открытым сертификатом... поэтому, грубо говоря, ему все равно каким сертификатом зашифровано письмо. Главное, чтобы подпись письма и само письмо были проверяемы методом Verify...

Или я не прав?
18.07.2005 10:29:38Kirill Sobolev
Еще как связан :) Но чем расшифровывать - действительно все равно.
Схема такая:
1)Verify получает сообщение и его подпись
2)Из подписи вытаскивается сертификат подписавшего
3)Этим сертификатом расшифровывается хэш, содержащийся в подписи
4)Считается хэш от сообщения
5)Эти хешы сравниваются

Если подменить зашифрованный хэш - то в п.3 хэш расшифруется не так, как надо, соотвественно п.5 не пройдет