我们有一个应用程序使用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,cptRSAFull,[ccVerify,ccMachineKeySet]); //Create a hash structure CryptCreateHash( fProvider.GetProviderHandle,chtSHA1,@fhHash); //Import the private key for signing CryptImportKey( fProvider.GetProviderHandle,@buff[0],len,CRYPT_EXPORTABLE,@fKey); //Hash the message CryptHashData(fhHash,@aPlainText[1],length(aPlainText) * 2,0); //Sign the message CryptSignHash(fhHash,AT_SIGNATURE,CRYPT_NOHASHOID OR CRYPT_X931_FORMAT,@buff,@len);
解决方法
设置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示例代码URL:http://msdn.microsoft.com/en-us/library/windows/desktop/aa382371%28v=vs.85%29.aspx