3

I'm working on a project where I have to encrypt and decrypt chosen files by user. How can I use a password from user as a key for AES encryption/decryption? Right now they can enter passwords of 8 or 16 characters long. I don't want to force the user to specify a password of 8 or 16 characters.

public static void EncryptFile(string file, string password)
{
    try
    {
        string outputFile = Path.GetFileNameWithoutExtension(file) + "-encrypted" + Path.GetExtension(file);
        byte[] fileContent = File.ReadAllBytes(file);
        UnicodeEncoding UE = new UnicodeEncoding();

        using (AesCryptoServiceProvider AES = new AesCryptoServiceProvider())
        {
            AES.Key = UE.GetBytes(password);
            AES.IV = new byte[16];
            AES.Mode = CipherMode.CBC;
            AES.Padding = PaddingMode.PKCS7;

            using (MemoryStream memoryStream = new MemoryStream())
            {
                CryptoStream cryptoStream = new CryptoStream(memoryStream, AES.CreateEncryptor(), CryptoStreamMode.Write);

                cryptoStream.Write(fileContent, 0, fileContent.Length);
                cryptoStream.FlushFinalBlock();

                File.WriteAllBytes(outputFile, memoryStream.ToArray());
            }
        }
    }
    catch (Exception ex)
    {
        MessageBox.Show("Exception thrown while encrypting the file!" + "\n" + ex.Message);
    }
}
zalaw
  • 33
  • 1
  • 3

1 Answers1

3

AES in .net uses by default a 256 bit key and a 128 bit IV .

SHA256 and MD5 hash algorithms create a 256 bit and a 128 bit hash respectively.

Hmmm.

byte[] passwordBytes = UE.GetBytes(password);
byte[] aesKey = SHA256Managed.Create().ComputeHash(passwordBytes);
byte[] aesIV = MD5.Create().ComputeHash(passwordBytes);
AES.Key = aesKey;
AES.IV = aesIV;
AES.Mode = CipherMode.CBC;
AES.Padding = PaddingMode.PKCS7;
Oguz Ozgul
  • 6,809
  • 1
  • 14
  • 26
  • Thank you! That is what I was looking for! – zalaw Apr 11 '20 at 18:02
  • 2
    You might want to look at adding a salt to the raw password for added security. Better still follow Klaus' suggestion of using a key derivation function like PKDF2. – rossum Apr 11 '20 at 19:28
  • 1
    With this approach, you need to completely re-write the encrypted data if you change the password. A more common approach is to encrypt the key and store the IV+key before the encrypted payload. That way, you only need to re-write the encrypted key if the user changes their password. You don't need to decrypt/encrypt all data again. Having said that, this approach works fine for situations where the password will not change. I use a similar approach for encrypting database backups before shipping to cloud storage. – Patrick Tucci Aug 07 '21 at 11:22
  • 1
    **SECURITY WARNING** This is not secure, this is just asking to be attacked using rainbow tables or even online lookup. Using MD5 is bad all in itself, using it for directly deriving keys is probably worse. – Maarten Bodewes Apr 11 '23 at 22:29