RSA - может зашифровать, но зашифрованное сообщение слишком велико для расшифровки - PullRequest
0 голосов
/ 08 ноября 2018

Редактировать: Благодаря совету от Лассе Вогстер Карлсен. Я смог решить мою проблему. Я использовал Bitconverter для преобразования байтов в строку, а затем использовал UTF8.GetBytes для преобразования их обратно в байты. Это не работает Я решил использовать

Convert.FromBase64String Convert.ToBase64String

Я пытаюсь внедрить RSA в программу клиент-сервер C #.

Мой план - создать открытый ключ на сервере и отправить его клиенту во время рукопожатия. Затем клиент сгенерирует ключ AES, зашифрованный открытым ключом RSA, и отправит его обратно на сервер. Затем я буду использовать AES для шифрования связи во время сеанса.

Проблема в том, что, когда Сервер получает зашифрованное Сообщение, я получаю сообщение об ошибке, в котором говорится, что файл превышает ограничения. Даже если зашифрованное сообщение на клиенте и когда служба получает его, имеют одинаковую длину и одинаковое содержание, если я преобразую их в строку XML для сравнения 2.

ошибка: System.Security.Cryptography.CryptographicException: расшифрованные данные превышают максимум для модуля на 256 байтов.

Отправка сериализованного открытого ключа клиенту:

RSAManager rSAManager = new RSAManager();

        string publicKeyString = SerializeKey(rSAManager.publicKey); // Serialize the public key so we can send it to the clients

        // Send test data to the remote device.
        Send(client, $"{publicKeyString}!");

Класс RSAManager:

public class RSAManager
{
#region Keys, Containername, Keysizes
public RSAParameters publicKey;
public RSAParameters privateKey;

static string CONTAINER_NAME = "MyContainerName";
public enum KeySizes
{
    SIZE_512 = 512,
    SIZE_1024 = 1024,
    SIZE_2048 = 2048,
    SIZE_952 = 952,
    SIZE_1369 = 1369
};


#endregion

#region Methods
public RSAManager()
{
    GenerateKeys();
}

public void GenerateKeys()
{
    using (var rsa = new RSACryptoServiceProvider(2048))
    {
        rsa.PersistKeyInCsp = false; //Don't store the keys in a key container
        publicKey = rsa.ExportParameters(false);
        privateKey = rsa.ExportParameters(true);
    }
}
/// <summary>
/// Encrypts the given byte array with the RSA standard
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
public byte[] Encrypt(string message)
{
    byte[] input = Encoding.UTF8.GetBytes(message);
    byte[] encrypted;
    using (var rsa = new RSACryptoServiceProvider(2048))
    {
        rsa.PersistKeyInCsp = false;
        rsa.ImportParameters(publicKey);
        encrypted = rsa.Encrypt(input, true);
    }
    return encrypted;
}
/// <summary>
/// Decrypts the given byte array with the RSA standard
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
public string Decrypt(byte[] encrypted)
{
    byte[] decrypted;
    using (var rsa = new RSACryptoServiceProvider(2048))
    {
        rsa.PersistKeyInCsp = false;
        rsa.ImportParameters(privateKey);
        decrypted = rsa.Decrypt(encrypted, true);
    }
    return Encoding.UTF8.GetString(decrypted);
}

Код, используемый для сериализации и десериализации:

Сериализация:

static string SerializeKey(RSAParameters publicKey)
{
    string publicKeyString;
    {
        //we need some buffer
        var sw = new System.IO.StringWriter();
        //we need a serializer
        var xs1 = new System.Xml.Serialization.XmlSerializer(typeof(RSAParameters));
        //serialize the key into the stream
        xs1.Serialize(sw, publicKey);
        //get the string from the stream
        publicKeyString = sw.ToString();
    }
    return publicKeyString;
}

Deserialize:

static RSAParameters DeSerializeKey(string publicKeyString)
{
    var sr = new System.IO.StringReader(publicKeyString);
    //we need a deserializer
    var xs = new System.Xml.Serialization.XmlSerializer(typeof(RSAParameters));
    //get the object back from the stream
    return (RSAParameters)xs.Deserialize(sr);
}

Получение, шифрование и отправка обратно клиенту

string publicKeyString = TrimString(new string[] {"!"},content);
RSAManager rSAManager = new RSAManager();

rSAManager.publicKey = DeSerializeKey(publicKeyString);

string randomAESKey = GetRandomString(40);
Console.WriteLine($"Randomstring: {randomAESKey");
byte[] encrypted = rSAManager.Encrypt(randomAESKey);
string encryptedAESKey = BitConverter.ToString(encrypted);
Console.WriteLine($"Encrypted. {encryptedAESKey}");
Console.WriteLine("Length of encrypted string: " + encryptedAESKey.Length);
// Echo the data back to the server.  
Send(handler, encryptedAESKey);

Сервер, получающий и дешифрующий ключ AES

// Write the response to the console.  
        Console.WriteLine("Length of encrypted response: " + response.Length);
        Console.WriteLine("Length of public Key: " + SerializeKey(rSAManager.publicKey).Length);
        // Decrypt functions needs byte array so we need to encode it. This line always causes the error.
        string encryptedResponse = rSAManager.Decrypt(Encoding.UTF8.GetBytes(response));
        // Received encrypted response
        Console.WriteLine($"Decrypted response: {encryptedResponse}");

Ответы [ 3 ]

0 голосов
/ 08 ноября 2018

По какой причине вы используете BitConverter при получении строки из зашифрованных байтов? Вы пытались использовать Encoding.UTF8.GetString?

0 голосов
/ 08 ноября 2018

Я настоятельно рекомендую вам использовать libsodium для решения этой проблемы. Их явная цель состоит в том, чтобы предоставить лучший API для криптографических операций, чтобы снизить вероятность того, что вы нарушите свою безопасность из-за неправильного использования библиотеки.

Кроме того, вы также подумали, как вы собираетесь аутентифицировать сервер? Возможно, вам не нужен вновь сгенерированный ключ RSA.

0 голосов
/ 08 ноября 2018

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

Эта ссылка на StackExchange содержит дополнительную информацию.

...