简体   繁体   中英

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?

Even if you can, never use a GUID for encryption key because they're not produced with a cryptographically secure random generator (CSRNG), so it's way easier to crack a GUID-based key than a securely generated key. Never use GUID for cryptographically sensitive operations.

I don't even recommend running a KDF over the GUID as that doesn't change the low entropy underneath.

As of .NET 6, it's way easier to generate a cryptographically secure random key:

byte[] key = RandomNumberGenerator.GetBytes(32); // generate 256-bits
byte[] iv = new byte[16];
byte[] array;
using var aes = Aes.Create();
aes.Key = Encoding.UTF8.GetBytes(key);
aes.IV = iv;

Everything about this is terribly broken.

16 bytes that represent a valid UTF8 string, is not very random. If I saw your code, I would be able to guess a significant fraction of the bits of your key.

.IV must always be unique. If you ever encrypt two different inputs with the same .Key & .IV , your encryption can be easily broken. It's common to generate a random IV and write it as plain text into the output. eg memoryStream.Write(aes.IV)

Using a salted hash to turn a password string into a key is better, but only if you can ensure that your salt is kept secret.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM