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