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, поэтому недоступен в справочном источнике.

Другие вопросы по тегам