20.02.2006 16:06:41smime.p7s и CryptVerifyDetachedMessageSignature Ответов: 13
Vlad
Добрый день.

Проверяю подпись почтового сообщения.
Сначала пытаюсь проверить сам файл .p7s с помощью
функции CryptVerifyMessageSignature, где в качестве сообщения указываю адрес smime.p7s полученный ч-з CreateFileMapping. Проверку не проходит и GetLastError возвращает CRYPT_E_HASH_VALUE.
Также пробую само сообщение проверить ч-з CryptVerifyDetachedMessageSignature и опять получаю
CRYPT_E_HASH_VALUE.

Не подскажите,где здесь ошибка?

Может .p7s надо предварительно перевести в какой-то формат.
Пробовал как сертификат открывать p7s и оттуда ключ извлекать и передавать в CryptVerifyDetachedMessageSignature, но тогда говорит - CRYPT_E_ASN1_BADTAG.
 
Ответы:
21.02.2006 9:39:22Kirill Sobolev
RFC 2633 + поищите по форуму S/MIME.
Еще для CryptVerifyMessageSignature сертификат подписчика должен быть в подписи.
21.02.2006 11:19:37Vlad
Я читал все эти RFC по S/MIME, и на форуме искал.
Наверное не совсем правильно вопрос задал.

Могут ли высокоуровневые функции типа CryptVerify(Detached)MessageSignature в принципе работать напрямую с файлами smime.p7* ?
Или надо все же низкоуровневыми функциями из него вытягивать нужные поля?

Пробовал проверять smime.p7s ч-з csptest.exe, он тоже ругается на неправильное значение хеша.
При проверке самого файла .p7s я конечно использовал сертификат подписывающей стороны. Виндовый менеджер сертификатов опознает этот файл и говорит, что с ним все в порядке.
21.02.2006 12:07:03Kirill Sobolev
Конечно можно. Это же PKCS7 - как раз то что нужно этим функциям.
Правда они в base64 скорее всего - если так, то нужно преобразовать в бинарный формат.
21.02.2006 17:11:46Vlad
Проверка самого сообщения ч-з CryptVerifyDetachedMessageSignature заработала.
(скорее всего это были глюки с типами в Дельфи, тоже самое на с++ пошло нормально)

А вот проверка smime.p7s(он в двоичном виде, не base64) так и не хочет производиться.

Или есть какие-то другие способы его проверки, не как зашифрованного сообщения,а как сертификата может?

Спасибо.
22.02.2006 11:27:28Kirill Sobolev
Я так и не понял, сама подпись detached или нет? Если работает CryptVerifyDetachedMessageSignature, то значит подпись detached и CryptVeirfyMessageSignature ee не проверит.
22.02.2006 12:54:11Vlad
само сообщение
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?
22.02.2006 13:05:16Kirill Sobolev
Все верно. Подпись у Вас отдельно от сообщения, поэтому функция для проверки detached подписи работает нормально. Само подписанное сообщение может либо входить в PKCS7 (тогда имеет смысл проверять его подпись CryptVerifyMessageSignature), либо нет (тогда CryptVerifyDetachedMessageSignature). Это 2 взаимоисключающих случая.
Объясните пожалуйста поподробнее чего именно Вы хотите добиться при "проверке подлинности самой подписи smime.p7s"?
CryptVerifyCertificateSignatureEx - это функция для проверки подписи сертификата, списка отзыва или запроса, но никак не подписанного сообщения, здесь она не подходит.
22.02.2006 15:06:36Vlad
Дак проверка сообщения ничего не стоит, если сама подпись(smime.p7s) фальшивая. Я вручную изменял содержимое smime.p7s и проверка сообщения все равно проходила успешно(только если сильно испоганить файл, тогда не проходит проверку), а если открыть этот битый smime.p7s с помощью стандарного менеджера сертификатов, то он ругается, что этот сертификат изменен и верить ему не стоит.

Так вот мне надо проверить на целостность всю цепочку сертификатов: от сертификата сообщения(smime.p7s),через сертификат пописывателя сообщения(.p7b) к корневому сертификату Крипто-Про. И после этого убедившись в целостности подписи и принадлежности ее к нужному отправителю, можно проверять подписью сообщение.
22.02.2006 15:11:47Kirill Sobolev
Ясно.
Функции *VerifyMessage используются именно для криптографической проверки - т.е. соотвествует ли сообщение подписи.
Для проверки цепочек нужно использовать другие : CertCreateCertificateChainEngine, CertGetCertificateChain
22.02.2006 17:19:33Vlad
Спасибо.
С этими функциями все правильно заработало.
22.02.2006 17:50:55Vlad
Еще вопрос: эти функции *Chain работают, если верить msdn только на NT, а есть какие-либо методы проверки сертификатов под 98 винду?
26.02.2006 8:58:27Vlad
В качестве заметки:
Если вдруг, кто-то пользуется модулем 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;
26.02.2006 10:09:53Kirill Sobolev
Работают и на 95/98, только вот
Requires Internet Explorer 5 or later on Windows 98 or Windows 95.