Я пытаюсь подписать закрытый ключ RSA в java и проверить его на C#. Код проверки хорошо работает на моем iMac с VS (xamarin), но всегда возвращает false в Windows 10. Код 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);
Есть идеи, в чем может быть проблема?
Спасибо





Если я проанализирую один и тот же открытый ключ в формате 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, но ответ, который я опубликовал, является обходным решением для Windows. Оба отлично работают на Mac. Я до сих пор не знаю, что не так с первым на windows. Было бы здорово, если бы кто-нибудь знал в чем проблема
Значение вашего модуля начинается с 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 (против 4096), а поскольку подпись составляет 512 байтов (вместо 513), это «автоматически неверно».
Теоретически альтернативным исправлением может быть добавление байта заполнения к подписи; но сделать значение модуля корректным для платформы кажется лучше.
Благодарить! модуль был экспортирован из java. byte[] modulusBytes = publicKey.getModulus().toByteArray(); Я отлаживал Mac, и он отлично работал с 0, но не работал в Windows. приятно знать причину этой проблемы
@keape А. Java должна была экспортировать его в стиле кодированных целочисленных данных PKCS1. Итак, Java хочет ведущий 0x00, и .NET может запутаться в этом :)
Не уверен, что это ответ. У вас остались вопросы / проблемы после этого?