加密 – Windows CryptoAPI:带有CALG_SHA_256的CryptSignHash和

我试图在 Windows上生成数字签名(来自XP SP3,但目前正在使用Windows 7进行测试),其中CryptoAPI将与以下openssl命令兼容: openssl dgst -sha256 -sign parameters (for signing)openssl dgst -sha256 -verify parameters (for validation) 我想使用Windows

我试图在
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)而失败.通过Google搜索around,我发现我需要使用特定的提供程序(PROV_RSA_AES)而不是默认的提供程序.由于我有一个提供者句柄,我还需要用CryptGetUserKey替换CryptAcquireCertificatePrivateKey.所以我修改了我的程序,看起来像:

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摘要一起使用.我很茫然,所以任何建议都会非常受欢迎!

解决方法

问题很可能是Windows上的证书“知道”它们的私钥存储在哪个提供程序中.当您导入证书时,它会将密钥放入某个提供程序类型(可能是PROV_RSA_FULL),当您稍后尝试通过证书访问密钥时,它可能最终会以相同的提供程序类型结束.

您可能需要打开证书的关联上下文(使用CERT_KEY_PROV_HANDLE_PROP_ID选项查看CertGetCertificateContextProperty).使用该句柄,您可以尝试从原始提供程序上下文导出密钥并重新导入新的PROV_RSA_AES(假设密钥是可导出的).

关于作者: dawei

【声明】:石家庄站长网内容转载自互联网,其相关言论仅代表作者个人观点绝非权威,不代表本站立场。如您发现内容存在版权问题,请提交相关链接至邮箱:bqsm@foxmail.com,我们将及时予以处理。

为您推荐