Search code examples
c#encryptioncryptographyaes.net-6.0

AES one-shot API decryption throwing if it has not encrypted before


I'm attempting to roundtrip crypting some data with the new .NET 6 AES one-shot APIs.

The following example works as expected:

using System.Security.Cryptography;

string key = "1234567890123456";
byte[] keyBytes = Encoding.ASCII.GetBytes(key);

string dec = "Hello One-Shot API!";
byte[] decBytes = Encoding.ASCII.GetBytes(dec);

// Encrypt
using Aes aes = Aes.Create();
byte[] encBytes = aes.EncryptCbc(decBytes, keyBytes);

// Decrypt again
byte[] recBytes = aes.DecryptCbc(encBytes, keyBytes);
string rec = Encoding.ASCII.GetString(recBytes);

Debug.Assert(rec == dec);

But if I create a new Aes instance to call DecryptCbc on, it throws a System.Security.Cryptography.CryptographicException: Padding is invalid and cannot be removed. exception:

...
// Encrypt
using Aes aes = Aes.Create();
byte[] encBytes = aes.EncryptCbc(decBytes, keyBytes);

// Decrypt again - this time with new instance
using Aes aes2 = Aes.Create();
byte[] recBytes = aes2.DecryptCbc(encBytes, keyBytes); // <- throws
...

Am I missing something here? Is there state set up in an Aes instance when calling EncryptCbc that doesn't exist when only using it for decryption? Do I have to keep the Aes instance around, and then how would I use it for decryption initially if I haven't encrypted with it before?


Solution

  • As mentioned in the comments, I mistook the IV parameter for the key, as I was porting old code not using any IV.

    Once setting the key in the Aes.Key property, and using an empty IV (or even better, fixing the old code and using a proper IV), it worked as expected with every new instance.