06.03.2007 9:38:38Функция CryptVerifySignature возвращает NTE_BAD_SIGNATURE Ответов: 2
Виктор
Пример взят из MSDN (Example C Program: Signing a Hash and Verifying the Hash Signature) и на майкрософтовском криптопровайдере работает :). А на вашем - не хочет.
Установлено Windows Xp, КриптоПро 2.0 (build 2100), картридер,носители - смарткарты.
Что делаю: (программа приводится без обработки ошибок)
const
ProvName = 'Crypto-Pro GOST R 34.10-2001 Cryptographic Service Provider';
var
hProv: HCRYPTPROV;
key, nKey: HCRYPTKEY;
publkey, signature: PBYTE;
publkeySiz, signatureSize: DWORD;
hash, hash1: HCRYPTHASH;

// подписывание
... вычисление имени контейнера FContName, находящегося на смарткарте
CryptAcquireContext(hProv, PChar(FContName), PChar(ProvName), 75, 0);
CryptGetUserKey(hProv, AT_KEYEXCHANGE, key);
CryptExportKey(key, 0, PUBLICKEYBLOB, 0, nil, publkeySiz);
CryptExportKey(key, 0, PUBLICKEYBLOB, 0, publkey, publkeySiz);
CryptCreateHash(hProv, CALG_SHA, 0, 0, hash);
... для внешнего файла с помощью CryptHashData создаю хэш
CryptSignHash(hash, AT_KEYEXCHANGE, nil, 0, nil, signatureSize);
CryptSignHash(hash, AT_KEYEXCHANGE, nil, 0, signature, signatureSize);
CryptDestroyHash(hash);

// проверка ЭЦП
CryptImportKey(hProv, publkey, publkeySiz, 0, 0, nKey);
CryptCreateHash(hProv, CALG_SHA, 0, 0, hash1);
... для внешнего файла с помощью CryptHashData создаю хэш 1
CryptVerifySignature(hash1, signature, signatureSize, nKey, nil, 0); - здесь выдает NTE_BAD_SIGNATURE!!!

Проверял:
1. пробовал обнулять ссылку на провайдера - CryptReleaseContext
а затем вновь вычислять с помощью CryptAcquireContext(hProv, nil, nil, 75, CRYPT_VERIFYCONTEXT)
но эффекта это не дало, поэтому ниже использую туже ссылку на провайдер, что и вверху
2. Сравнил хэшы, созданные и во время подписи, и во время верификации - совпадают.
3. Использование AT_SIGNATURE в CryptGetUserKey выдает NTE_NO_KEY
В чем мои действия неправильны?
 
Ответы:
06.03.2007 10:08:57Kirill Sobolev
CryptCreateHash(hProv, CALG_SHA, 0, 0, hash) - для нашего CSP это неправильно, нужно CryptCreateHash(hProv, CALG_GR3411, 0, 0, hash). Для MS провайдера конечно будет работать.
06.03.2007 10:47:11Виктор
Ха! Действительно так.
Спасибо!