我正在尝试在Java中使用RSA私钥进行签名,并在C#中对其进行验证。验证代码在带有VS(xamarin)的iMac上可以正常运行,但在Windows 10上始终返回false。C#代码在此处:
RSAParameters rsaPars = new RSAParameters();
rsaPars.Modulus = Convert.FromBase64String("AKZXGikjSCLZT2CfhPguEA4ZDVEmCBwNvSVagkPFDnz3kLvbSXus51stJ7iUedocrGWgeilbVJoKP9cTqtZ8dyRwpokU55Kixk5JFf+5wS/SZtPs84eHPDfTC9C9Gg97/krFyGq7fikdoJpuRQBaBh1qqxGA6C+vzO49xGIiWeUA0+u9M2/PA/y7EhgZngKhhzGiU+KWhawctFAokCFX9kBhgmxVxM6EyJdD3RppEnhsza6VORHcnTnOgetZJML9WE7FX8sDO82DvnCv4UIR5YzN8W8nqLLp/RZyZkzmRGXIItUYW2VEvTV6/I2SVLNrKJNgKIYD2SOOSHXw/+RD5RcGFf1jsLP/ZF8JxAayywjDwCY0FsvyWHrWJMPPWQWPw30+Nk6pqY9OIiD/Z7xCTdmO6H8xV/SRyKRe8YdAS6Wuro6l/MnoPv+eqh/gc958RkC7BQmWtzN/UDbx/bqU4nJ2YLF37ZeKjMjqea7n3aOO/pwMQSqp96E/CImprm5lXdso+/RPzAslktMaTom++/4wtr4mxynDy+KPml9qDFCxHpvuIxF1w8fBaBKTpBXQlgi5o0ZdbXl5kalYjnkMbZ903bcSC1tEbhMVQCSJ5qvCulKWMWmbB5HWSx1QRcVkz0fUVuYfrm20m0MXSpgpZkGSU7gouI7W/Q9nMN9HCLUj");
rsaPars.Exponent = Convert.FromBase64String("AQAB");
string signature = "doBEnIGZXCtzI7Iwfl3akr2Jk+jtDloXjZeB8aeEmpoElpqPNevC3z9tNRC1yCsmECx9a92hj9E5Z2QXY5bvHxsxf9uH2INcdN4ORBQxWH5znI3qLIMVjXMJ7NM2g+5S64weCV3YDH8+93q2zUX/dvoJNYuUTn4ZeTZIoIuuIdHssZn+tRQt8smYX1FIbLnS+2catX76hfpgJPrAQE2eukDdnJ5S/mIN09+G4mI9a3n9FNUVr2b7+uUGfX9RabUQwHjZK64kUTWui+j1GEDKXf2Lb0TjTwM+AuAAwKcOHttoX8Np3z+AQsRQfQe8XFxyEWaVwgf77R+Xru0e+z2ASF392xpuDQDdDQoMuaKpFn6FvFgs5FHM1v/YGm3QD1IgJfslZ7DmHZh25g6kg5scj3D2nQtnM8CfPdQNIA8r4cjLgESgx5O30s/K5liNeTlGdIj+mhZZ8ZHldi+Kps5Tk/rtkWSkdKylzFb6p6JVZRRa7Ks0Z52oKoGVcPWQbALYu08I1KILynGwVIWy4fgf9BzvbAWhCnfkVynl5gfNaDKSuuysTEOM1l08YfeSnpR8D4NZeOJuKnZT1dKbHqNGpCK7sXpLaaP0UZhCcBfW55wBADE7vhbX5HcL3bXLbFbsrA5/CO9AHrz7f8Xx+VQdv+qS1YixzHb1o741c6EK6qw=";
byte[] dataToSign = Encoding.UTF8.GetBytes("Data to Sign");
using (RSACryptoServiceProvider RSA = new RSACryptoServiceProvider(4096))
{
RSA.ImportParameters(rsaPars);
Console.WriteLine(RSA.VerifyData(dataToSign, "SHA1", Convert.FromBase64String(signature)));
}
我在Mac和Windows上都运行了确切的代码。一开始我以为是编码问题。我在Mac和Windowns上比较了这些原始数据,它们是相同的。如果我在C#代码中生成了 key ,则它在Windows上可以正常工作。
privateKey = RSAalg.ExportParameters(true);
publicKey = RSAalg.ExportParameters(false);
知道这可能是什么问题吗?
谢谢
最佳答案
您的Modulus值以0x00开头,可能是因为Xamarin/Mono不正确地导出了它。
如果您重新编码模量值以删除前导0x00(或执行类似操作
if (rsaPars.Modulus[0] == 0)
{
byte[] tmp = new byte[rsaPars.Modulus.Length - 1];
Buffer.BlockCopy(rsaPars.Modulus, 1, tmp, 0, tmp.Length);
rsaPars.Modulus = tmp;
}
),那么您的问题就会消失。
大概在Windows 10中发生了一些变化,它没有意识到前导字节为0x00,因此它认为 key 大小为4104(与4096),并且由于签名为512字节(而不是513),因此“自动不正确”。
从理论上讲,另一种解决方法是在签名中添加一个填充字节。但是将Modulus值设为平台正确似乎更好。
关于c# - RSACryptoServiceProvider无法在Windows上验证,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/49493281/