CryptographicException в RSA.ImportParameters() - неверные данные в специальных 1024 ключах
У нас есть приложение C#/.NET 4.0, которое импортирует частные ключи RSA из строки в Base64, полученной в WebService.
Это приложение отлично работает для RSA-ключей в 1024 битах, но не работает со специальным видом секретных ключей RSA (около 1% ключей).
Вот длина в байтах:
Работа-Key:
- Модуль => 128 байт
- Экспонент => 3 байта
- D => 128 байт
- P => 64 байта
- Q => 64 байта
- DP => 64 байта
- DQ => 64 байта
- IQ => 64 байта
Не-рабочий-Key:
- Модуль => 128 байт
- Экспонент => 3 байта
- D => 127 байт
- P => 64 байта
- Q => 64 байта
- DP => 64 байта
- DQ => 64 байта
- IQ => 64 байта
Разница в длине D (128 работает, 127 не работает). Неработающий ключ на 1 байт короче рабочего ключа.
Параметры устанавливаются, но при выполнении RSA.ImportParameters(rsaParams) он генерирует исключение CryptographicException с сообщением "Bad Data".
Что нужно включить для решения этой проблемы?
1 ответ
RSACryptoServiceProvider
имеет некоторые предположения о длине данных, которые:
- Модуль: любой четный размер, назовем длину
n
- Экспонент: (
<= 4
байт; хотя RSACng допускает "любой размер"), давайте назовем длинуe
- D:
n
- П:
n/2
- Q:
n/2
- DP:
n/2
- DQ:
n/2
- InverseQ:
n/2
Итак, если предположить, что ваш второй ключ на самом деле является модулем: 128 байтов (поскольку 64-байтовый P, умноженный на 64-байтовый Q, не является 256-байтовым числом), вам просто нужно дополнить массив D массивом нуля, чтобы получить это до надлежащей длины.
byte[] newD = new byte[modulus.Length];
Buffer.BlockCopy(d, 0, newD, newD.Length - d.Length, d.Length);
.NET Core имеет исходный код, показывающий эту связь. В.NET Framework он скрыт внутри CLR, поэтому недоступен в справочном источнике.