RSACng 无法验证哈希



我有一个旧的代码块,它使用我想移植过来使用较新的RSACngRSACryptoServiceProvider。我遇到了一个我无法解决的问题:RSACngVerifyHash方法似乎没有按预期验证哈希。相同的代码和数据,当与RSACryptoServiceProvider一起使用时,工作正常,验证成功。

我做了一些调查和.NET源代码步进,最终一直到NCryptVerifySignature。我确保哈希、签名等都与RSACryptoServiceProvider相同。最后,由于未知原因,在这种情况下,NCryptVerifySignature无法成功验证哈希。

我的代码如下:

var rsaKeyPub = "BgIAAACkAABSU0ExAAgAAAMAAAC7N02Zb0lf3UO4pl3ymFvkrNSkPP0Q076vYzvbeTqS5vkBcoXloM044q1LCFtaXw6DUzSFM0IqoGOONb+PW+UeNcTcA/+MKNi7nzbBGg3kAj8QhuxO3u2QJXg62Zb9H+SEvZYfi9PhOCSo0LpWKl72k+uaoTyPAuV738TamRvXWb8XOswSmsHQa38q1Id4TW7CzvVOjc0vnhL+rZ8Po1qg5FJc8m8gdGWC0a4NJTzBsOqLzeVE12B8zgIMehu1gGw/SjY5PVEkDABWgY2DzxLT3rbs6oZ5ZLSHu041q3s1ihOQ8+GMRx3qqvPyB4JVlyd7jqN0j0dT+Yqr+8t3/Liu";
var hash = "Ow1kg47GAgf9cyZbisDuTRNy5NQ=";
var signature = "bBnFouYvuZSYZIPihDB4J/CVC7o5ej3MrbkZV9cn6vgL23rDW1jevWEHx4wGBXLc443DKrZ0XQlSpp3FE/+isyDMcGh7c0buMufiYuOQ0rbo8e4tvuZuZpt+06xnBQcYyFMqe4lkFcI0f/NeAIvy1vME+Kq4v3ikwR4+CsjObgEJIBdWB0B4cqp8355pxtYJv2BQ7UHy/Tv0+OtslgbxikrwU2CQ+tR3XHywIdzm0BEOBfdnOlky96ED18BAqwLlxjef0snCl3DvKz93gtIIQVwEoDRlKC/v/Xb4Eke/fyvt66orLEIyL8Emaer9J6P38ZB1pWRuOsLCv4ly8fnOMw==";
RSAParameters rsaParams;
using (var rsa = new RSACryptoServiceProvider())
{
rsa.ImportCspBlob(Convert.FromBase64String(rsaKeyPub));
//Export now for easy importing in the next function. This is not the reason the next block returns false.
rsaParams = rsa.ExportParameters(false);
Console.WriteLine(rsa.VerifyHash(Convert.FromBase64String(hash), Convert.FromBase64String(signature), HashAlgorithmName.SHA1, RSASignaturePadding.Pkcs1));
}
using (var rsa = new RSACng())
{
rsa.ImportParameters(rsaParams);
Console.WriteLine(rsa.VerifyHash(Convert.FromBase64String(hash), Convert.FromBase64String(signature), HashAlgorithmName.SHA1, RSASignaturePadding.Pkcs1));
}

有人对我做错了什么有任何建议吗?这是使用最新的.NET Framework(4.7.2)。

我对此进行了一些深入研究,问题是因为签名在通过 OpenSSL 运行时:

openssl rsautl -verify -in sig.bin -inkey pub.key -pubin -hexdump -raw介绍:

0000 - 00 01 ff ff ff ff 0010 - ff ff ff ff 0020 - FF FF ff 0030 - FF ff 0040 - ff ff ff ff 0050 - FF ff 0060 - ff ff ff ff 0070 - FF ff 0080 - FF ff ff ff 0090 - ff ff ff ff 00a0 - ff ff ff ff 00b0 - ff ff ff ff 00C0 - ff ff ff ff ff 00d0 - ff ff ff ff 00e0 - ff ff ff ff ff-ff ff ff 00 3b 0d 64 83 ............;.d. 00f0 - 8e c6 02 07 fd 73 26 5b-8a c0 ee 4d 13 72 e4 d4 .....s&[...M.r..

本质上,您有一个带有 PKCSv1.5 填充的签名,末尾带有哈希。但是,签名缺少SEQUENCE(OID(SHA-1), OCTETSTRING)- 摘要直接进入。

CNG 希望 OID 按照 RSASSA-PKCS1-v1_5 中的定义存在。你可以要求CNG放宽这个要求,将NULL传递给BCRYPT_PKCS1_PADDING_INFOpszAlgId,但是据我所知,这在.NET Framework或Core的任何地方都没有公开。

至于如何修复它,如果可能的话,现在最简单的事情是使用CAPI/RsaCryptoServiceProvider。GitHub 问题 34202 可能会跟踪有关 CNG 行为的任何其他进度。

最新更新