[英]RSACng fails to verify hash
I have an old code block that uses RSACryptoServiceProvider
that I wanted to port over to use the newer RSACng
. 我有一个旧的代码块,使用
RSACryptoServiceProvider
,我想移植到使用较新的RSACng
。 I have run into a problem that I am unable to solve: RSACng
's VerifyHash
method doesn't appear to verify the hash as expected. 我遇到了一个我无法解决的问题:
RSACng
的VerifyHash
方法似乎没有按预期验证哈希。 The same code and data, when used with RSACryptoServiceProvider
, works fine and the verification succeeds. 与
RSACryptoServiceProvider
使用时,相同的代码和数据工作正常,验证成功。
I have done some investigation and .NET source stepping, eventually going all the way down to NCryptVerifySignature
. 我做了一些调查和.NET源步骤,最终一直到
NCryptVerifySignature
。 I made sure the hash, signature, etc are all the same that RSACryptoServiceProvider
works with. 我确保散列,签名等与
RSACryptoServiceProvider
工作方式完全相同。 In the end, for unknown reasons, NCryptVerifySignature
is not successful in verifying the hash in this case. 最后,由于未知原因,
NCryptVerifySignature
在这种情况下无法验证散列。
My code is below: 我的代码如下:
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));
}
Does anyone have any advice on what I am doing wrong? 有没有人对我做错了什么有任何建议? This is using the latest .NET Framework (4.7.2).
这是使用最新的.NET Framework(4.7.2)。
I dug at this a bit and the issue is because the signature, when run through OpenSSL via: 我挖了一下这个问题是因为签名,当通过OpenSSL运行时:
openssl rsautl -verify -in sig.bin -inkey pub.key -pubin -hexdump -raw
presents: openssl rsautl -verify -in sig.bin -inkey pub.key -pubin -hexdump -raw
:
0000 - 00 01 ff ff ff ff ff ff-ff ff ff ff ff ff ff ff ................ 0010 - ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff ff ................ 0020 - ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff ff ................ 0030 - ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff ff ................ 0040 - ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff ff ................ 0050 - ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff ff ................ 0060 - ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff ff ................ 0070 - ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff ff ................ 0080 - ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff ff ................ 0090 - ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff ff ................ 00a0 - ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff ff ................ 00b0 - ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff ff ................ 00c0 - ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff ff ................ 00d0 - ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff ff ................ 00e0 - ff ff ff 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..
Essentially you have a signature with PKCSv1.5 padding with the hash at the end. 基本上你有一个带有PKCSv1.5填充的签名,最后是哈希。 However, the signature is missing the
SEQUENCE(OID(SHA-1), OCTETSTRING)
- the digest is going straight in. 但是,签名缺少
SEQUENCE(OID(SHA-1), OCTETSTRING)
- 摘要直接进入。
CNG expects the OID to be there as defined in RSASSA-PKCS1-v1_5. CNG希望OID在RSASSA-PKCS1-v1_5中定义。 You can ask CNG to relax this requirement by passing in NULL to the
BCRYPT_PKCS1_PADDING_INFO
's pszAlgId
, however this is not exposed anywhere in .NET Framework or Core as far as I know. 您可以通过将NULL传递给
BCRYPT_PKCS1_PADDING_INFO
的pszAlgId
来请求CNG放宽此要求,但据我所知,这不会在.NET Framework或Core中的任何地方公开。
As far as how to fix it, the easiest thing right now if possible is to use CAPI / RsaCryptoServiceProvider. 至于如何修复它,如果可能的话,现在最简单的方法是使用CAPI / RsaCryptoServiceProvider。 GitHub issue 34202 may track any additional progress on CNG's behavior.
GitHub问题34202可以跟踪CNG行为的任何其他进展。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.