| ||||
| ||||
Добрый день. Проверяю подпись почтового сообщения. Сначала пытаюсь проверить сам файл .p7s с помощью функции CryptVerifyMessageSignature, где в качестве сообщения указываю адрес smime.p7s полученный ч-з CreateFileMapping. Проверку не проходит и GetLastError возвращает CRYPT_E_HASH_VALUE. Также пробую само сообщение проверить ч-з CryptVerifyDetachedMessageSignature и опять получаю CRYPT_E_HASH_VALUE. Не подскажите,где здесь ошибка? Может .p7s надо предварительно перевести в какой-то формат. Пробовал как сертификат открывать p7s и оттуда ключ извлекать и передавать в CryptVerifyDetachedMessageSignature, но тогда говорит - CRYPT_E_ASN1_BADTAG. | ||||
Ответы: | ||||
| ||||
RFC 2633 + поищите по форуму S/MIME. Еще для CryptVerifyMessageSignature сертификат подписчика должен быть в подписи. | ||||
| ||||
Я читал все эти RFC по S/MIME, и на форуме искал. Наверное не совсем правильно вопрос задал. Могут ли высокоуровневые функции типа CryptVerify(Detached)MessageSignature в принципе работать напрямую с файлами smime.p7* ? Или надо все же низкоуровневыми функциями из него вытягивать нужные поля? Пробовал проверять smime.p7s ч-з csptest.exe, он тоже ругается на неправильное значение хеша. При проверке самого файла .p7s я конечно использовал сертификат подписывающей стороны. Виндовый менеджер сертификатов опознает этот файл и говорит, что с ним все в порядке. | ||||
| ||||
Конечно можно. Это же PKCS7 - как раз то что нужно этим функциям. Правда они в base64 скорее всего - если так, то нужно преобразовать в бинарный формат. | ||||
| ||||
Проверка самого сообщения ч-з CryptVerifyDetachedMessageSignature заработала. (скорее всего это были глюки с типами в Дельфи, тоже самое на с++ пошло нормально) А вот проверка smime.p7s(он в двоичном виде, не base64) так и не хочет производиться. Или есть какие-то другие способы его проверки, не как зашифрованного сообщения,а как сертификата может? Спасибо. | ||||
| ||||
Я так и не понял, сама подпись detached или нет? Если работает CryptVerifyDetachedMessageSignature, то значит подпись detached и CryptVeirfyMessageSignature ee не проверит. | ||||
| ||||
само сообщение Content-Type: text/plain Content-Transfer-Encoding: base64 UlJFQ1YNCkZST006IO/v7yD... успешно проверяется detached подписью smime.p7s ч-з CryptVerifyDetachedMessageSignature. но еще кроме этого надо проверить подлинность самой подписи smime.p7s. Вот ее пробую проверить ч-з CryptVerifyMessageSignature, и проверка не проходит, возвращая CRYPT_E_HASH_VALUE. Еще пробовал проверять smime.p7s как сертификат ч-з CryptVerifyCertificateSignatureEx, но тоже не получается, т.к. проверяются только X509_ASN_ENCODING, а здесь PKCS_7_ASN_ENCODING. Может как-нибудь конвертировать подпись в X509_ASN_ENCODING? | ||||
| ||||
Все верно. Подпись у Вас отдельно от сообщения, поэтому функция для проверки detached подписи работает нормально. Само подписанное сообщение может либо входить в PKCS7 (тогда имеет смысл проверять его подпись CryptVerifyMessageSignature), либо нет (тогда CryptVerifyDetachedMessageSignature). Это 2 взаимоисключающих случая. Объясните пожалуйста поподробнее чего именно Вы хотите добиться при "проверке подлинности самой подписи smime.p7s"? CryptVerifyCertificateSignatureEx - это функция для проверки подписи сертификата, списка отзыва или запроса, но никак не подписанного сообщения, здесь она не подходит. | ||||
| ||||
Дак проверка сообщения ничего не стоит, если сама подпись(smime.p7s) фальшивая. Я вручную изменял содержимое smime.p7s и проверка сообщения все равно проходила успешно(только если сильно испоганить файл, тогда не проходит проверку), а если открыть этот битый smime.p7s с помощью стандарного менеджера сертификатов, то он ругается, что этот сертификат изменен и верить ему не стоит. Так вот мне надо проверить на целостность всю цепочку сертификатов: от сертификата сообщения(smime.p7s),через сертификат пописывателя сообщения(.p7b) к корневому сертификату Крипто-Про. И после этого убедившись в целостности подписи и принадлежности ее к нужному отправителю, можно проверять подписью сообщение. | ||||
| ||||
Ясно. Функции *VerifyMessage используются именно для криптографической проверки - т.е. соотвествует ли сообщение подписи. Для проверки цепочек нужно использовать другие : CertCreateCertificateChainEngine, CertGetCertificateChain | ||||
| ||||
Спасибо. С этими функциями все правильно заработало. | ||||
| ||||
Еще вопрос: эти функции *Chain работают, если верить msdn только на NT, а есть какие-либо методы проверки сертификатов под 98 винду? | ||||
| ||||
В качестве заметки: Если вдруг, кто-то пользуется модулем wcrypt2 в Delphi, то надо исправить описание функции CryptVerifyDetachedMessageSignature, чтобы она правильно работала, следующим образом: type pacarPbyte = packed array of Pbyte; pacarDWORD = packed array of DWORD; ------------------------ function CryptVerifyDetachedMessageSignature(pVerifyPara :PCRYPT_VERIFY_MESSAGE_PARA; dwSignerIndex :DWORD; const pbDetachedSignBlob :PBYTE; cbDetachedSignBlob :DWORD; cToBeSigned :DWORD; const rgpbToBeSigned :pacarPbyte; rgcbToBeSigned :pacarDWORD; ppSignerCert :PPCCERT_CONTEXT):BOOL ; stdcall; | ||||
| ||||
Работают и на 95/98, только вот Requires Internet Explorer 5 or later on Windows 98 or Windows 95. | ||||