2016-12-15 8 views
0

Я пытаюсь использовать открытый ключ пользователя, чтобы зашифровать строку в своем роде pgp моды, но я получаю сообщение об ошибке:C# .net ядро ​​шифрование

bignum routines:BN_mod_inverse:no inverse 

Я осмотрелся и я не могу найти ничего конкретного относительно того, что я делаю неправильно. Я просмотрел основную информацию .NET, но я не могу найти ничего подходящего.

Я использую следующий код:

byte[] publicKey = Encoding.UTF8.GetBytes(key); 

RSA rsa = RSA.Create(); 
RSAParameters RSAKeyInfo = new RSAParameters(); 

RSAKeyInfo.Modulus = publicKey; 
RSAKeyInfo.Exponent = new byte[]{1,0,1}; 

rsa.ImportParameters(RSAKeyInfo); 
var encrypted = rsa.Encrypt(Encoding.UTF8.GetBytes(user.challenge.text), RSAEncryptionPadding.Pkcs1); 

Это вполне возможно, я буду об этом совершенно неправильно, так что любые мысли или предложения было бы здорово!

+0

Открытый ключ состоит из байтов, это не строка. Кроме того, он обычно состоит из кодирования модуля и общественного показателя, а не только модуля. Используйте OAEP, чтобы получить что-то безопасное. –

ответ

2

Ваша общая структура (постройте RSAP-параметры, вызовите ImportParameters, вызовите Encrypt), что говорит о том, что ваша ошибка связана с восстановлением модуля.

Если модуль вводится как строка, это, вероятнее всего закодирован как (большинство наименее)

  • Base64 (Convert.FromBase64String)
  • Hex (Может потребоваться ручной анализатор)
  • UTF- 8

UTF-8 действительно маловероятно, так как величина модуля упругости может содержать байты, значение которых содержит 0 (и другие недопустимые/неожиданные UTF-8 последовательностей). Хотя все байтовые последовательности с четной длиной, закодированные как шестнадцатеричные, могут быть корректно декодированы как Base64, чрезвычайно маловероятно, чтобы вы неправильно интерпретировали их с учетом двух или трех разных входов.

Другие примечательные вещи:

  • RSA является IDisposable, вы должны поместить его в using заявление, чтобы обеспечить ресурсы высвободить раньше, когда вы закончите с ними.
  • Показатель обычно 0x010001, но это не требуется. Если у вас нет гарантированного ограничения на это, вы также должны сериализовать его.
    • И если это всегда будет 0x010001, зачем каждый раз создавать новый? Сохраните его как статическое поле и упростите работу GC.
  • Как сказал Мартен, RSA-ENC-PKCS1 восприимчив к атаке оскорбления обивки, поэтому (особенно если ваши данные перегружены), вы должны использовать OAEP.
    • В контексте .NET у OaepSHA1 есть лучшая поддержка (все поставщики входящих сообщений). OAEP с алгоритмом SHA-2 поддерживается только RSACng (или непрозрачным RSA.Create() в Windows).
+0

Оказывается, это было 'UTF-8'. Я получил ключ от javascript-клиента, а бронированные ключи должны быть бронированными ASCII, но вместо этого использовались 'UTF-8'. Было всего несколько деталей реализации, которые у нас были. Благодаря! – crodeheaver