| ||||
| ||||
Есть простенький почтовый клиент на 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. | ||||
Ответы: | ||||
| ||||
"Неизвестный криптографический алгоритм" а КриптоПро CSP установлен? (если они конечно ГОСТом подписывают) | ||||
| ||||
:) Подписывают ГОСТом. Установил CSP. Ошибка изменилась на : Неправильное значение хэша... :) | ||||
| ||||
Проверяете подпись не того сообщения. Вот тут аналогичная проблема http://www.cryptopro.ru/CryptoPro/forum/myforum.asp?q=1588 + еще надо учесть что текст в CAPICOM передается юникодный, а Rapida.dll подписывает ASCII, т.е. надо преобразовывать. | ||||
| ||||
Спасибо. "Проверяете подпись не того сообщения" - это исключено. А вот RFC 2633 - это довольно интересно. Как я понял, В CAPICOM нужно засунуть текст (в юникоде) + к нему добавить шапку Content-Type: text/plain Content-Transfer-Encoding: base64 Но тогда шапка будет противоречить сообщению. Оно же уже не в base64... или же в CAPICOM нужно сначала сам текст перевести из base64 в koi (первоначальный текст в кои), а потом уже добавить шапку и все загнать в юников - capicom ? | ||||
| ||||
Извиняюсь, неточно выразился. "Не то" - значит "не то, что было изначально подписано". Как раз я имел ввиду, что заголовки тоже нужны. В CAPICOM как раз нужно засунуть текст в ASCII (binary string). Причем именно тот, что пришел в письме - без всяких преобразований из base64 | ||||
| ||||
Встречено неверное значение тега ASN1 :) Как я понял CAPICOM ругается, когда текст и подпись подсовываешь ему в byte[]. Но, мне кажется, я где-то читал у Вас на форуме, что эти errors можно пропустить... Это на самом деле так? | ||||
| ||||
Так, по порядку. Если в письме подпись отдельно от сообщения, то в Content записывается binary string, преобразованная из юникода, а в Verify передается юникодный base64 Если же подпись вместе с сообщением, то это все подсовывается в Verify | ||||
| ||||
Подпись отдельно от сообщения, т.е.: "в Content записывается binary string, преобразованная из юникода" т.е. я пишу: SigText=Encoding.ASCII.GetString(Encoding.Unicode.GetBytes(SigText)); ===================================== "в Verify передается юникодный base64" а вот это я несовсем понял. Юникодный base64 - это вот так: Signature=Encoding.Unicode.GetString(Convert.FromBase64String(Signature)); Ошибка : в asn1 встречен неожиданный конец данных... Понимаю, что уже ничего не понимаю :) | ||||
| ||||
Если в письме подпись отделно и в base64, то ее вообще никуда преобразовывать не надо. | ||||
| ||||
:) Ладно... Не буду Вас больше мучить... Спасибо... | ||||
| ||||
Возник еще вопрос: а работает ли вообще метод Verify ? Я что-то никак не пойму, почему нигде нет упоминания о сертификате? Т.е. любой, кто перехватит письмо, сможет изменить содержимое, создать новый хеш и выслать нам. Хеш будет подходить к этому письму... и все дела. Или же я где-то ошибся в использовании функции? ПС Как только не подставлял хеш и текст. Всегда пишет : Неправильное значение хеша. | ||||
| ||||
Работает :) Информация о сертификате содержится в подписи. Подпись - это не просто хеш, а зашифрованный секретным ключем отправителя. Т.е. если злоумышленник подменит подпись, у получателя не получится ее правильно расшифровать. | ||||
| ||||
"Т.е. если злоумышленник подменит подпись, у получателя не получится ее правильно расшифровать." Очень странно, ведь метод Verify никак не связан даже с открытым сертификатом... поэтому, грубо говоря, ему все равно каким сертификатом зашифровано письмо. Главное, чтобы подпись письма и само письмо были проверяемы методом Verify... Или я не прав? | ||||
| ||||
Еще как связан :) Но чем расшифровывать - действительно все равно. Схема такая: 1)Verify получает сообщение и его подпись 2)Из подписи вытаскивается сертификат подписавшего 3)Этим сертификатом расшифровывается хэш, содержащийся в подписи 4)Считается хэш от сообщения 5)Эти хешы сравниваются Если подменить зашифрованный хэш - то в п.3 хэш расшифруется не так, как надо, соотвественно п.5 не пройдет | ||||