Cryptoapi 签名/验证在 Windows 8.1 上不起作用

Posted

技术标签:

【中文标题】Cryptoapi 签名/验证在 Windows 8.1 上不起作用【英文标题】:Cryptoapi sign/verify not working on Windows 8.1 【发布时间】:2013-11-08 14:54:24 【问题描述】:

我们有一个应用程序,它使用 CryptoApi 使用 SHA1 哈希对消息进行签名和验证。它在 WindowsXP 到 Windows 8 下已经完美运行多年。它不再在 Windows 8.1 上运行。 CryptSignHash 失败,错误代码为 87(无效参数)。 CryptVerifySignature 不会失败,但会返回 NTE_BAD_SIGNATURE(对于在 Windows 8 上创建的有效签名)。我们已经测试了我们所能做的一切......它在 Windows 8 及更低版本上运行,在 Windows 8.1 上失败。

您对如何进一步调试有任何想法吗? 我们再次导出导入的公钥和私钥,并验证它们是正确的。 我们跳过了使用“我们的”密钥并生成了新密钥 -> 签名也失败并出现错误 87 我们使用 RSA_FULL 和 DES 生成新密钥并使用它们加密/解密消息 -> 没问题,按预期工作。 我们检查了 RSA_FULL 提供程序的版本。它在 Windows 8 和 Windows 8.1 上都是 2.0。 我们尝试明确指定提供程序名称:Microsoft Base Cryptographic Provider v1.0

在 Windows 8.1 上签名对你们中的任何人都有效吗?

Windows 8.1 上还有什么新功能吗?这可能会阻止签名工作? 我们应该知道的提供者或算法是否发生了变化?

应用程序是用Delphi编写的,使用大致如下流程:

//Setup crypto provider 
CryptAcquireContext(@fhCryptProv, nil, nil,  cptRSAFull, [ccVerify, ccMachineKeySet]); 

//Create a hash structure
CryptCreateHash( fProvider.GetProviderHandle, chtSHA1, 0, 0, @fhHash);

//Import the private key for signing
CryptImportKey( fProvider.GetProviderHandle, @buff[0], len, 0, CRYPT_EXPORTABLE, @fKey);

//Hash the message
CryptHashData(fhHash, @aPlainText[1], length(aPlainText) * 2, 0);

//Sign the message
CryptSignHash(fhHash, AT_SIGNATURE, nil, CRYPT_NOHASHOID OR CRYPT_X931_FORMAT, @buff, @len);

【问题讨论】:

【参考方案1】:

当设置 CRYPT_X931_FORMAT 标志时,CryptSignHash 在 Windows 8.1 上失败。这看起来像 Windows 8.1。漏洞。

可以通过从下面的 url 运行 MSDN 示例代码来重现此错误,使用 CALG_SHA1 而不是 CALG_MD5 进行散列并将 CryptSignHash 中的标志设置为 CRYPT_NOHASHOID | CRYPT_X931_FORMAT;将标志保留为 0 或仅保留在 CRYPT_NOHASHOID 在我测试过的系统上工作。

在 WindowsXP 到 Windows 8.0 系统上这些标志我从来没有遇到过任何问题。

MSDN 示例代码网址:http://msdn.microsoft.com/en-us/library/windows/desktop/aa382371%28v=vs.85%29.aspx

【讨论】:

以上是关于Cryptoapi 签名/验证在 Windows 8.1 上不起作用的主要内容,如果未能解决你的问题,请参考以下文章

[加密解密]CryptoAPI简介

我在后端使用 PyNacl 进行数字签名。我应该在前端使用哪个库?

农业银行上网银里CryptoAPI私钥是啥东西啊

将 PEM 编码的 X.509 证书加载到 Windows CryptoAPI

CryptoAPI C++ 使用 AES 与 Java 互操作

对于我签名的驱动程序,“Windows 无法验证数字签名”——怎么办?