0

I'm using microsoft's RSACryptoServiceProvider class to Encrypt/Decrypt data. However, decryption function throws an exception "Bad Data". Is it something about creating new instance of the provider class everytime I use encryption/decryption?

RSA Provider Class

 static public byte[] RSAEncrypt(byte[] byteEncrypt, RSAParameters RSAInfo, bool isOAEP)
    {
        try
        {
            using (RSACryptoServiceProvider RSA = new RSACryptoServiceProvider())
            {
                RSA.ImportParameters(RSAInfo);

                //Encrypt the passed byte array and specify OAEP padding.
                return RSA.Encrypt(byteEncrypt, isOAEP);
            }
        }
        catch (CryptographicException e)
        {
            Console.WriteLine(e.Message);
            return null;
        }
    }

    static public byte[] RSADecrypt(byte[] byteDecrypt, RSAParameters RSAInfo, bool isOAEP)
    {
        try
        {
            using (RSACryptoServiceProvider RSA = new RSACryptoServiceProvider(4096))
            {
                //Import the RSA Key information. This needs
                //to include the private key information.
                RSA.ImportParameters(RSAInfo);

                //Decrypt the passed byte array and specify OAEP padding.
                return RSA.Decrypt(byteDecrypt, isOAEP);
            }
        }
        catch (CryptographicException e)
        {
            Console.WriteLine(e.ToString());
            return null;
        }
    }
}

Usage

  UnicodeEncoding ByteConverter = new UnicodeEncoding();
  RSACryptoServiceProvider RSA = new RSACryptoServiceProvider(4096);
  byte[] plainPassword;
  byte[] encryptedPassword;

  plainPassword = ByteConverter.GetBytes(connectionStringPasswordTextBox.Text);
  encryptedPassword = CryptoHelper.RSAEncrypt(plainPassword, RSA.ExportParameters(false), false);
  RSACryptoServiceProvider RSA = new RSACryptoServiceProvider(4096);
  byte[] decryptedPassword = CryptoHelper.RSADecrypt(Convert.FromBase64String(connectionString.password), RSA.ExportParameters(true), false);

EDIT

The exception has changed to "The parameter is incorrect" after giving a few more try. I think it has to do with creating only one instance for rsa class instaead of creating new one everytime I use it.

3
  • Have you checked out this: stackoverflow.com/questions/9659898/…? Commented Aug 15, 2016 at 13:14
  • 1
    Yes, I was so desperate to even look up google's 2nd page. Commented Aug 15, 2016 at 13:19
  • Interesting, the issue is caused by the creation a new key set when the second RSACryptoServiceProvider is created. There is however mention of a "default key" in MSDN (msdn.microsoft.com/en-us/library/zseyf239(v=vs.110).aspx), but no documentation about what that actually means. Commented Aug 15, 2016 at 14:06

1 Answer 1

1

The RSACryptoServiceProvider(int) constructor generates a new key (unless CAPI returns a key for the null-name; which I'm not sure is possible). So this code is encrypting with one key and attempting to decrypt with another. The resulting answer makes so little sense that an exception is thrown.

  • Generate your key once, and save the RSAParameters from it.
  • To make your code more portable, avoid saying "RSACryptoServiceProvider"; just talk about RSA, when possible.
    • Unfortunately, key creation is a time it isn't possible since RSACryptoServiceProvider doesn't generate a new key when KeySize is changed.

So you should really use something more like this on .NET 4.6 or higher:

public static byte[] RSAEncrypt(
    byte[] byteEncrypt,
    RSAParameters rsaInfo,
    RSAEncryptionPadding padding)
{
    try
    {
        using (RSA rsa = RSA.Create())
        {
            rsa.ImportParameters(rsaInfo);
            return rsa.Encrypt(byteEncrypt, padding);
        }
    }
    catch (CryptographicException e)
    {
        Console.WriteLine(e.Message);
        return null;
    }
}
Sign up to request clarification or add additional context in comments.

4 Comments

It says "Method does not supported" for Encrypt or Decrypt method.
Are you calling Encrypt(byte[], RSAEncryptionPadding) or EncryptValue(byte[])? The latter does throw a NotSupportedException. If you don't see the one which takes an RSAEncryptionPadding you're probably targeting .NET 4.5.2 or lower (it's new in 4.6). See msdn.microsoft.com/en-us/library/… and msdn.microsoft.com/en-us/library/…
It doesnt let me call Encrypt method and when I call EncryptValue method, it throws NotSupportedException
Right, EncryptValue has never worked. If you can't call the new Encrypt(byte[], RSAEncryptionPadding) method you're compiling against something older than 4.6 (or you are using mono), in which case there's nothing you can really do better than what you have (aside from avoiding generating a new key when you don't mean to).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.