Я пытаюсь сгенерировать цифровые подписи в Windows (из XP SP3, но в настоящее время тестирую с Windows 7) с CryptoAPI, который будет совместим со следующими командами openssl:
openssl dgst -sha256 -sign <parameters> (for signing)
openssl dgst -sha256 -verify <parameters> (for validation)
Я хочу использоватьзакрытый ключ из хранилища ключей Windows MY для подписи.
Мне удалось подписать файлы с помощью алгоритма дайджеста SHA1, используя следующие функции CryptoAPI (для краткости опущены параметры):
CertOpenStore
CertFindCertificateInStore
CryptAcquireCertificatePrivateKey
CryptCreateHash (with CALG_SHA1)
CryptHashData
CryptSignHash
Сгенерированная подпись совместима с «openssl dgst -sha1 -verify» (после изменения порядка байтов).
Моя проблема: при попытке использовать CALG_SHA_256 с CryptCreateHash происходит сбой с ошибкой 80090008 (NTE_BAD_ALGID),Погуглив вокруг , я обнаружил, что мне нужно использовать определенного провайдера (PROV_RSA_AES) вместо поставщика по умолчанию.Поскольку у меня был бы дескриптор провайдера, мне также нужно заменить CryptAcquireCertificatePrivateKey на CryptGetUserKey.Поэтому я изменил свою программу так:
CryptAcquireContext (with PROV_RSA_AES)
CertOpenStore
CertFindCertificateInStore
CryptGetUserKey
CryptCreateHash (with CALG_SHA256)
CryptHashData
CryptSignHash
К сожалению, это не сработало, как ожидалось: CryptGetUserKey завершился ошибкой 8009000D (NTE_NO_KEY).Если я удалю вызов CryptGetUserKey, программа будет работать до CryptSignHash, которая завершается с ошибкой 80090016 (NTE_BAD_KEYSET).Я знаю, что набор ключей существует и работает нормально, так как я смог использовать его для подписи дайджеста SHA1.
Я попытался снова получить контекст с информацией из контекста сертификата, полученного из CertFindCertificateInStore: лучшее, что я могdo был успешным вызовом CryptGetUserKey, но CryptSignHash всегда завершался ошибкой с одной и той же ошибкой.
Закрытый ключ, который я пытаюсь использовать, имеет длину 2048 бит, но я не ожидаю, что это будет проблемой, поскольку он работаетс дайджестом SHA1.Я в растерянности, поэтому любое предложение будет очень кстати!