无法使用 xml (X509Certificate2) 中提供的证书公钥验证签名值
本文关键字:证书 公钥 验证 xml X509Certificate2 | 更新日期: 2023-09-27 18:35:19
>我花了100多个小时研究这个主题,其他编写原始项目的高级程序员也无法使其工作。我有一个带有签名值、证书 (X509Certificate2) 和摘要值参数的 xml。在同一 xml 中声明的创建和给定的签名值是通过将串联字段(等于摘要值)转换为哈希 (SHA1),然后通过私钥加密来实现的。为了隐私起见,私钥已从证书中取出,我只有公钥。现在,无论我如何编码,我总是得到一个错误的值(如VerifyHash/verifyHashResult is false)。这是我正在使用的代码:
请帮忙。
static void VerifyHash(string sigVal , string digestVal, System.Security.Cryptography.X509Certificates.X509Certificate2 cert)
{
sigValInBytes = Convert.FromBase64String(sigVal);
try
{
using (RSACryptoServiceProvider rsaProviderDecrypt = (RSACryptoServiceProvider)cert.PublicKey.Key)
{
// Line below always return value of FALSE no matter how I code it. Here I want to verify the hashed freshly calculated digest value that is now hashed with the signature value
rsaProviderDecrypt.Decrypt(sigValInBytes, false);
rsaProviderDecrypt.Dispose();
}
}
}
// At the main program I get the certificate from the xml given and call the method above:
main
{
// Code below gets the certificate details from a given xml, details of each variable confirmed to be accurate.
char[] Base64_x509ByteArray;
Base64_x509ByteArray = t.DigitalSignatures.First().X509Data.ToCharArray();
byte[] x509ByteArray;
x509ByteArray = Convert.FromBase64CharArray(Base64_x509ByteArray, 0, Base64_x509ByteArray.Length);
// Here am creating the certificate from the gathered data/certificate:
System.Security.Cryptography.X509Certificates.X509Certificate2 cert = new System.Security.Cryptography.X509Certificates.X509Certificate2(x509ByteArray);
VerifyHash(t.DigitalSignatures.FirstOrDefault().SignatureValue.Trim(), concatenatedFieldValues, cert);
}
黑暗中的一些镜头:
-
找到损坏的部分:尝试在代码中执行整个"加密/哈希检查"过程,而无需通过XML传输任何内容。 如果可以在本地对字符串进行哈希处理,并且哈希匹配,则问题出在 XML 中。否则,问题出在证书或解密器中。
-
如果问题出在证书/加密器端,请尝试与本地 .NET 加密类进行哈希匹配。 如果失败,则问题出在加密设置上。否则,它是证书。
-
黑暗中的大镜头:哈希检查后立即调用
Dispose
。 这应该没关系,但这在我使用 Rijndael 算法解密时引起了问题。最好的猜测是优化器提前关闭流或类似的事情。 将构造函数移出using
语句并在访问结果后手动调用Dispose
修复了"优化"。 -
可能会尝试可逆的加密算法。Rinjdael 是 .NET 的原生版本,并且是可逆的。 适用于调试和概念验证工作。(注意:它使用时间作为盐的一部分,所以 RJ 不匹配哈希,它会解密。因此,对于生产环境中的密码不好。
-
如果 XML 是原因,请检查编码。加密对编码非常敏感,XML 序列化程序一开始就是一头笨拙的野兽。字符串可能看起来相同,但表示方式不同,或者添加了额外的控制字符。Sql Server nvarchars 是 UCS-2,varchars 是 iso-8859-1,C# 字符串是 utf-8,等等。 编码很容易不匹配,编码更改很容易导致这种情况。在插入到 XML 之前,请尝试将原始值转换为
utf-16
,并将 Xml 声明编码设置为utf-16
。只是为了安全起见。
关于记事本 的注意事项:如果您在记事本中打开了 Xml 以快速查看或编辑并保存了它,那么您的字符串上现在可能有额外的"行尾"字符。 如果您在 Word 中执行了相同的操作...天呐... 可能想尝试原始副本。
如果失败,请尝试生成新的加密值,看看它们是否匹配。