Jonas Stawski
Jonas Stawski

Reputation: 6752

What is the default padding for AesCryptoServiceProvider?

I am getting the error Padding is invalid and cannot be removed while trying to decrypt a string using AesCryptoServiceProvider. According to this question I need to specify the same padding on both the Encryption and Decryption algorithms. The problem I have is that there is already data that has been encrypted without the explicit padding. What is the default padding that was used in that case so I can explicitly set it?

Here's the code being used:

public static byte[] EncryptStringToBytes(string plainText, byte[] Key, byte[] IV)
{
  // Check arguments. 
  if (plainText == null || plainText.Length <= 0)
    throw new ArgumentNullException("plainText");
  if (Key == null || Key.Length <= 0)
    throw new ArgumentNullException("Key");
  if (IV == null || IV.Length <= 0)
    throw new ArgumentNullException("Key");
  byte[] encrypted;
  // Create an AesCryptoServiceProvider object 
  // with the specified key and IV. 
  using (AesCryptoServiceProvider aesAlg = new AesCryptoServiceProvider())
  {
    aesAlg.Key = Key;
    aesAlg.IV = IV;
    // Create a decrytor to perform the stream transform.
    ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV);

    // Create the streams used for encryption. 
    using (MemoryStream msEncrypt = new MemoryStream())
    {
      using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
      {
        using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
        {
          //Write all data to the stream.
          swEncrypt.Write(plainText);
        }
        encrypted = msEncrypt.ToArray();
      }
    }
  }
  // Return the encrypted bytes from the memory stream. 
  return encrypted;
}

public static string DecryptStringFromBytes(byte[] cipherText, byte[] Key, byte[] IV)
{
  // Check arguments. 
  if (cipherText == null || cipherText.Length <= 0)
    throw new ArgumentNullException("cipherText");
  if (Key == null || Key.Length <= 0)
    throw new ArgumentNullException("Key");
  if (IV == null || IV.Length <= 0)
    throw new ArgumentNullException("Key");

  string plaintext = null;
  using (AesCryptoServiceProvider aesAlg = new AesCryptoServiceProvider())
  {
    aesAlg.Key = Key;
    aesAlg.IV = IV;

    ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV);
    using (MemoryStream msDecrypt = new MemoryStream(cipherText))
    {
      using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
      {
        using (StreamReader srDecrypt = new StreamReader(csDecrypt))
        {
          plaintext = srDecrypt.ReadToEnd();
        }
      }
    }
  }
  return plaintext;
}

The Key and the IV are being retrieved using Rfc2898DeriveBytes given a password and a salt. Bellow is the code:

public static void GetKeyAndIVFromPasswordAndSalt(string password, byte[] salt, SymmetricAlgorithm symmetricAlgorithm, ref byte[] key, ref byte[] iv)
{
  Rfc2898DeriveBytes rfc2898DeriveBytes = new Rfc2898DeriveBytes(password, salt);
  key = rfc2898DeriveBytes.GetBytes(symmetricAlgorithm.KeySize / 8);
  iv = rfc2898DeriveBytes.GetBytes(symmetricAlgorithm.BlockSize / 8);
}

Upvotes: 1

Views: 8014

Answers (1)

Ichabod Clay
Ichabod Clay

Reputation: 2011

The default modes for symmetric algorithms can be found in the SymmetricAlgorithm Properties page on the MSDN. In this case, PaddingMode.PKCS7 is the default padding mode used.

Be aware, however, that this specific Cryptographic Exception can be thrown in different circumstances as well. If your Key and/or IV aren't the exact same ones that were used in the encryption of your data then this exception will be thrown. The second answer in the question you linked discusses this.

Upvotes: 3

Related Questions