Надеюсь, это полезно. :-)
аюсь сгенерировать цифровые подписи в Windows (из XP SP3, но в настоящее время тестирую в Windows 7) с CryptoAPI, который будет совместим со следующими командами openssl:
openssl dgst -sha256 -sign <parameters> (for signing)
openssl dgst -sha256 -verify <parameters> (for validation)
Я хочу использовать закрытый ключ из хранилища ключей Windows «МОЙ» для подписи.
Мне удалось подписать файлы, используя алгоритм дайджеста 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: лучшее, что я мог сделать, был успешный вызов CryptGetUserKey, но CryptSignHash всегда будет терпеть неудачу с той же самой ошибкой.
Закрытый ключ, который я пытаюсь использовать, имеет длину 2048 бит, но я не ожидаю, что это будет проблемой, так как он работает с дайджестом SHA1. Я в растерянности, поэтому любое предложение будет очень кстати!