Taf Munyurwa
Taf Munyurwa

Reputation: 1572

Bad data exception when decrypting using RSA with correct private and public key pair in C#

This is my code for decryption process:

    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);
    }

The encryption code:

        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);
    }

I can not see where I am going wrong. I have made sure that the keys are correct. The public one which i extracted using this line in the constructor: _publicKey = _rsa.ToXmlString(false); This public key is displayed on the form that I created. The private i used the "true" instead of false.

Any ideas?

Upvotes: 1

Views: 5484

Answers (1)

Jon Skeet
Jon Skeet

Reputation: 1499770

Ciphertext is very unlikely to be genuinely UTF-16-encoded text. Assuming that the encryption side had something like:

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

you've basically lost data. The result of encryption is not text - it's arbitrary binary data. If you want to convert that to text for some transport reason, you should use Base64, e.g.

string base64EncryptedText = Convert.ToBase64String(encryptedBytes);

Then use Convert.FromBase64String to recover the original encrypted binary data which is ready to decrypt.

Upvotes: 5

Related Questions