Исключение неверных данных при расшифровке с использованием RSA с правильной парой закрытого и открытого ключей в С#

Это мой код для процесса расшифровки:

    private RSACryptoServiceProvider _rsa;
    private string _privateKey;
    private string _publicKey;

    public RsaLibrary()
    {
        //initialsing the RSA object taking the option of a 1024 key size
        _rsa = new RSACryptoServiceProvider(1024);
        _privateKey = _rsa.ToXmlString(true);
        _publicKey = _rsa.ToXmlString(false);

    }

 public string Decrypt(string ciphertext, string privateKey_ = null)
    {
        if (String.IsNullOrEmpty(privateKey_))
        {
            return DecryptToBytes(ciphertext, _privateKey);
        }
        else
        {
            return DecryptToBytes(ciphertext, privateKey_);
        }
    }

    private string DecryptToBytes(string ciphertext, string privateKey)
    {
        if (String.IsNullOrEmpty(privateKey))
        {
            throw new ArgumentNullException("Error: No key provided.");
        }
        if (ciphertext.Length<=0)
        {
            throw new ArgumentNullException("Error: No message to decrypt.");
        }

        byte[] plaintext;
        byte[] ciphertext_Bytes = Encoding.Unicode.GetBytes(ciphertext);
        _rsa.FromXmlString(privateKey);

        plaintext = _rsa.Decrypt(ciphertext_Bytes, false);

        return Encoding.Unicode.GetString(plaintext);
    }

Код шифрования:

        private string EncryptToByte(string plaintext, string publicKey)
    {
        if (String.IsNullOrEmpty(publicKey))
        {
            throw new ArgumentNullException("Error: No key provided.");
        }
        if (plaintext.Length<=0)
        {
            throw new ArgumentNullException("Error: No message to incrypt");
        }


        byte[] ciphertext;
        byte[] plaintext_Bytes = Encoding.Unicode.GetBytes(plaintext);
        _rsa.FromXmlString(publicKey);

        ciphertext = _rsa.Encrypt(plaintext_Bytes, false);
        return Convert.ToBase64String(ciphertext);
    }

Я не вижу, где я ошибаюсь. Я убедился, что ключи правильные. Общедоступный, который я извлек с помощью этой строки в конструкторе: _publicKey = _rsa.ToXmlString(false); Этот открытый ключ отображается в форме, которую я создал. В привате я использовал «true» вместо «false».

Любые идеи?


person Taf Munyurwa    schedule 01.04.2013    source источник


Ответы (1)


Очень маловероятно, что зашифрованный текст будет действительно текстом в кодировке UTF-16. Предполагая, что на стороне encryption было что-то вроде:

string encryptedText = Encoding.Unicode.GetString(encryptedBytes);

вы в основном потеряли данные. Результатом шифрования является не текст — это произвольные двоичные данные. Если вы хотите преобразовать это в текст по какой-либо транспортной причине, вы должны использовать Base64, например.

string base64EncryptedText = Convert.ToBase64String(encryptedBytes);

Затем используйте Convert.FromBase64String для восстановления исходных зашифрованных двоичных данных, готовых к расшифровке.

person Jon Skeet    schedule 01.04.2013
comment
я согласен, у меня была похожая проблема, я конвертировал в 32 байта вместо 16 байтов. - person dekdev; 01.04.2013
comment
Я добавил дополнительную информацию о том, как зашифрованы. Будет ли проблема в том, что я получаю текст для шифрования из поля RichText и текст для расшифровки также из поля RichText. Я думал, что весь текст в UTFF-16 в Windows, который является UNICODE. Вот почему я общался с использованием UNICODE - person Taf Munyurwa; 01.04.2013
comment
@TafMunyurwa: отредактируйте код шифрования в своем вопросе — не публикуйте его в качестве комментария. - person Jon Skeet; 01.04.2013
comment
Сейчас исправил, большое спасибо за помощь - person Taf Munyurwa; 02.04.2013