4

我们有一个使用 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);
4

1 回答 1

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

于 2013-11-13T21:45:45.317 回答