0

I am using the following:

 RijndaelManaged rm = new RijndaelManaged();
 encryptor = rm.CreateEncryptor(key, vector);
 decryptor = rm.CreateDecryptor(key, vector);
 rm.Padding = PaddingMode.None;

This works good for me. However when I try to intentionally use an incorrect key I get an exception when decoding here:

public byte[] Decrypt(byte[] buffer) {
 MemoryStream decryptStream = new MemoryStream();
 using (CryptoStream cs = new CryptoStream(decryptStream, decryptor, CryptoStreamMode.Write)) {
  cs.Write(buffer, 0, buffer.Length);
 }
 return decryptStream.ToArray();
}

System.Security.Cryptography.CryptographicException was unhandled by user code
  Message=Padding is invalid and cannot be removed.

Is there some way I can cleanly manage this and is this to be expected if I on purpose use the WRONG key?

Now I changed this to the following based on a suggestion below:

public byte[] Decrypt(byte[] buffer)
    {
        try {
            MemoryStream decryptStream = new MemoryStream();
            using (CryptoStream cs = new CryptoStream(decryptStream, decryptor, CryptoStreamMode.Write))
            {
                cs.Write(buffer, 0, buffer.Length);
            }
            return decryptStream.ToArray();
        } catch(CryptographicException e){
            //... do something with it ...
            return null;
        }
    }

How can I pass up the exception to the next method which is:

public string DecryptFromUrl(string encrypted)
{
    return Decrypt(HttpUtility.UrlDecode(encrypted));
}
  • It's unclear what you're asking. What do you mean by "cleanly manage"? What's the bigger context? Clearly you won't be able to use whatever data you're trying to decrypt... the impact of that will depend on the application. – Jon Skeet Jun 30 '11 at 07:30
  • Hello John. When the right key is used all is okay. If a user was to try and access data that's not allowed they would be using the wrong key. I would like my code to be able to respond cleanly to this. I guess the Decrypt method would throw an exception somehow and then that would be handled by the code that calls it and up the tree. Right now I just get an exception and the code stops. I've not used exceptions so I am not familiar with how to handle them with try blocks etc. – LotsOfQuestions Jun 30 '11 at 07:33
  • See http://stackoverflow.com/questions/11762/c-cryptographicexception-padding-is-invalid-and-cannot-be-removed/26283#26283 is more or less the same question, and yes, it is expected. – Jorge Córdoba Jun 30 '11 at 07:34
  • Yes, the code that calls it would catch the exception and handle it. This feels like it's a question more about catching exceptions than cryptography... I don't think I'd return null from the Decrypt method though; I'd catch the exception higher up. – Jon Skeet Jun 30 '11 at 07:40
  • Thanks John. I put in the null as without it then it gave me an error saying "not all code has a return path". I will mark below answered and open another questions just about exceptions. – LotsOfQuestions Jun 30 '11 at 07:46

2 Answers2

1

In any case you should be try { ... } catching() the error and handling it from there. You could return a specific error, generic error, log it etc depending on your requirements.

try
{
... code ...
}
catch(CryptographicException e)
{
... do something with it ...
}
TheITGuy
  • 722
  • 4
  • 15
0

It's ok for the Decrypt method to throw an exception when it can't decrypt - that's what the exceptions are used for. However, it would be better to throw some custom exception insted of the System.Security.Cryptography.CryptographicException which is specific to your current implementation. For example, you may change the Decrypt method to do this:

public byte[] Decrypt(byte[] buffer)
{
    MemoryStream decryptStream = new MemoryStream();
    try
    {
        using (CryptoStream cs = new CryptoStream(decryptStream, decryptor, CryptoStreamMode.Write))
        {
            cs.Write(buffer, 0, buffer.Length);
        }
    }
    catch ( CryptographicException ex )
    {
        throw new InvalidKeyException(ex);
    }
    return decryptStream.ToArray();
}

Where InvalidKeyException is a class that derives from System.Exception. Now, assuming the decrypt method is part of a class called EncryptionProvider, you can call it like this:

EncryptionProvider encryptionProvider;
// initialize the encryptionProvider with the key
try
{
    byte[] decryptedData = encryptionProvider.Decrypt( encryptedData );
    // use decryptedData here - it's decrypted with the correct key
}
catch ( InvalidKeyException )
{
    // Handle the "wrong key" case here. You may notify the user that they are 
    // not  authorized to access this information or something similar,
    // depending on your application logic
}
Georgi Stoyanov
  • 1,208
  • 1
  • 11
  • 13