Как зашифровать длинную строку с помощью RSA, используя пользовательский открытый ключ и формат заполнения - PullRequest
0 голосов
/ 06 февраля 2019

поэтому я столкнулся с проблемой, что мне нужно зашифровать строку размером от 450 до 470 байт.У меня есть только открытый ключ от хостера сервера, на который я хочу отправить зашифрованное сообщение для входа.Проблема в том, что открытый ключ не является стандартным, он модифицируется хост-сервером для соответствия его криптосистеме.Они использовали Java для шифрования, но я создал программный плагин в c #.Так как я могу зашифровать с помощью данного ключа мою строку?

Открытый ключ:

Они сказали мне, что их ключ разделен так:

48015250 4 байта "Магия"

01 1 байт Номер версии

00000101 4 байта Длина модуля: 0x0101 = 257 байт

00970348 ... C1D257 байт Модуль

00000003 4 байта Длина экспоненты: 0x0003 = 3 байта

010001 3 байта Экспонент: 0x010001 = 65537

Я создал открытый ключ в c # с показателем степении модуль из их ключа

private static string m_strModulus = "00970348B03E911DCCE5ED8F555C2116DBC4D7E96D4C1CDC4BBBAAD26BAA54B5C834F604F9DFB391459459772FB51D00AFD0FE3A9B2DA724E62113A9E8C95BEF377CB5FCF7FEBE42E5282A0DA50F01D5D2635DD958F9836CFB4F8B616777C0CF67DB9A5530AD679E321972E4D4F4F33DED057CB690417A3B42FBFCE2AD9FDD80C815AF1EC858C796D4EA2F17954E4BFAD08E3E0397FA34122AC5951D889B06359A401E5506E50FA176B5A77FAB84E25CFCDBF2330AA173DA1156C8B79D6DB6BFAE828B00811183E63F137648E1FC1786B52D815C248BCADDDF6A17C941414F67A23ADFE82FE76196B64B96E36F8604FA00E8E357F5AE6C83B992D622D5E9CD9C1D";
private static string m_strExponent = "010001";
string xmlPublicKey = "<RSAKeyValue><Modulus>" + m_strModulus + "</Modulus><Exponent>" + m_strExponent + "</Exponent></RSAKeyValue>";

и использовал RSACryptoServiceProvider.FromXmlString (myOwnPublicXmlKeyGeneratedFromTheirs) для шифрования сообщения входа в систему.

rsa.FromXmlString(xmlPublicKey);

, так как у меня есть большая строка, я зашифровал все это блоками по 245 байт:

private const int m_nKeySize = 2048;  // The RSA key length
private const int _EncryptionBufferSize = 245;
private const int _DecryptionBufferSize = 256;

using (MemoryStream ms = new MemoryStream())
      {
        //Create a buffer with the maximum allowed size
        byte[] buffer = new byte[_EncryptionBufferSize];
        int pos = 0;
        int copyLength = buffer.Length;
        while (true)
        {
          //Check if the bytes left to read is smaller than the buffer size, then limit the buffer size to the number of bytes left
          if (pos + copyLength > byData.Length)
          {
            copyLength = byData.Length - pos;
          }
          //Create a new buffer that has the correct size
          buffer = new byte[copyLength];
          //Copy as many bytes as the algorithm can handle at a time, iterate until the whole input array is encoded
          Array.Copy(byData, pos, buffer, 0, copyLength);
          //Start from here in next iteration
          pos += copyLength;
          //Encrypt the data using the public key and add it to the memory buffer
          //_DecryptionBufferSize is the size of the encrypted data
          ms.Write(rsa.Encrypt(buffer, false), 0, _DecryptionBufferSize);
          //Clear the content of the buffer, otherwise we could end up copying the same data during the last iteration
          Array.Clear(buffer, 0, copyLength);
          //Check if we have reached the end, then exit
          if (pos >= byData.Length)
            break;
        }

Они также упоминали, что используют дополнение TBC (Trailing Bit Complement)алгоритм, и я не нашел никакой реализации для этого в C # только в Java, который я не могу использовать.

Сервер отвечает мне ошибкой, что открытый ключ неверен или устарел, или синтаксис сообщения неверен.Я уже могу общаться с сервером без шифрования, и поэтому текст для шифрования должен быть в порядке.

Насколько я знаю, я не правильно использую их открытый ключ, потому что он специально создан для этих целей.

Кто-нибудь знает, как решить этот конкретный случай?

Редактировать:

Я преобразовал шестнадцатеричные значения модуля и экспоненты в значения base64, я забыл упомянутьтот.Я использовал следующий метод:

public static string HexStringtoB64String(string input)
{
  return System.Convert.ToBase64String(HexStringToByteArray(input));
}

и использовал их непосредственно перед созданием экземпляра rsa следующим образом:

m_strModulus = HexStringtoB64String(m_strModulus);
m_strExponent = HexStringtoB64String(m_strExponent);
...