Search code examples
c#encryption-symmetric

I am using GUID as key and it's throwing error Specified key is not a valid size for this algorithm


I have below method for symmetric encryption a string content,

 public static class EncodeExtension
{
    public static string AesEncryptString(this string plainText, string key)
    {
        byte[] iv = new byte[16];
        byte[] array;

        using (Aes aes = Aes.Create())
        {
            aes.Key = Encoding.UTF8.GetBytes(key);
            aes.IV = iv;

            ICryptoTransform encryptor = aes.CreateEncryptor(aes.Key, aes.IV);

            using (MemoryStream memoryStream = new MemoryStream())
            {
                using (CryptoStream cryptoStream = new CryptoStream((Stream)memoryStream, encryptor, CryptoStreamMode.Write))
                {
                    using (StreamWriter streamWriter = new StreamWriter((Stream)cryptoStream))
                    {
                        streamWriter.Write(plainText);
                    }

                    array = memoryStream.ToArray();
                }
            }
        }

        return Convert.ToBase64String(array);
    }
}

Now I want to pass a random Guid as a key for each string content string,

var key1 = Guid.NewGuid().ToString();
var encryptedData = "test1".AesEncryptString(key1);


var key2 = Guid.NewGuid().ToString();
var encryptedData = "test2".AesEncryptString(key2);

Here I am getting Specified key is not a valid size for this algorithm? What key size it's expecting here? I do generate a random key size ?


Solution

  • This error comes from the fact that the size in bytes of the GUID UTF8 string isn't a valid key size for AES (128, 192 or 256 bits).

    You could use a key derivation function such as PBKDF2 to derive the key from your GUID. PBKDF2 is implemented in .net by the class Rfc2898DeriveBytes

    public static string AesEncryptString(this string plainText, string key) {
        byte[] array;
        byte[] keyBytes;
    
        using (Aes aes = Aes.Create())
        {
            using (Rfc2898DeriveBytes pbkdf = new Rfc2898DeriveBytes(key, Encoding.UTF8.GetBytes(key)))
            {
                // here 16 bytes for AES128
                keyBytes = pbkdf.GetBytes(16);
            }
    
            aes.Key = keyBytes;
            //for convenience here we use the key as iv too
            aes.IV = keyBytes;
    
            ICryptoTransform encryptor = aes.CreateEncryptor(aes.Key, aes.IV);
    
            using (MemoryStream memoryStream = new MemoryStream())
            {
                using (CryptoStream cryptoStream = new CryptoStream((Stream)memoryStream, encryptor, CryptoStreamMode.Write))
                {
                    using (StreamWriter streamWriter = new StreamWriter((Stream)cryptoStream))
                    {
                        streamWriter.Write(plainText);
                    }
    
                    array = memoryStream.ToArray();
                }
            }
        }
    
        return Convert.ToBase64String(array); 
     }
    

    Be careful as you will have to use the same behavior to generate the key on decryption too.