RSACryptoServiceProvider无法在Windows

时间:2018-03-26 13:58:56

标签: c# windows rsa

我正在尝试使用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#代码中生成了密钥,它在Windows上运行良好。

privateKey = RSAalg.ExportParameters(true);
publicKey = RSAalg.ExportParameters(false);

知道这可能是什么问题吗?

由于

2 个答案:

答案 0 :(得分:1)

你的模数值以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,所以它认为密钥大小是4104(vs 4096),并且由于签名是512字节(而不是513),它&#39 ; s"自动不正确"。

理论上,另一种修复方法是在签名中添加填充字节;但是将模数值设为平台校正似乎更好。

答案 1 :(得分:0)

如果我以xml格式解析相同的公钥,它可以同时适用于mac和windows

RSAParameters rsaPars;
using (RSACryptoServiceProvider RSA = new RSACryptoServiceProvider(4096))
{
    RSA.FromXmlString(@"<RSAKeyValue><Modulus>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</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>");
    rsaPars = RSA.ExportParameters(false);
}

它看起来将模数和指数直接设置为Windows上的公钥并不起作用