emrekizildas / EntityFrameworkCore.EncryptColumn

Encrypt & Decrypt your databases columns using EntityFramework Core.
MIT License
87 stars 40 forks source link

Null IV? #15

Open SeanTalley opened 1 year ago

SeanTalley commented 1 year ago

Is this code using a null IV?

I don't see where you read/write the IV anywhere... this doesn't seem right to me... seems like the IV is just null.

Am I missing something?

flo2000ace commented 1 year ago

No i also thought this, this is not good for security reasons and also does concern me

SeanTalley commented 1 year ago

Here is how I corrected the code if you want to implement it. @emrekizildas

This also adds a salt and a pepper:

using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;
using EntityFrameworkCore.EncryptColumn.Interfaces;

namespace EntityFrameworkCore.EncryptColumn.Util
{
    public class GenerateEncryptionProvider : IEncryptionProvider
    {
        private readonly string key;
        private readonly RandomNumberGenerator rng = RandomNumberGenerator.Create();
        public GenerateEncryptionProvider(string key)
        {
            this.key = key;
        }

        public string Encrypt(string dataToEncrypt)
        {
            if (string.IsNullOrEmpty(key))
                throw new ArgumentNullException("EncryptionKey", "Please initialize your encryption key.");

            if (string.IsNullOrEmpty(dataToEncrypt))
                return string.Empty;

            byte[] iv = new byte[16];
            rng.GetBytes(iv);
            byte[] salt = new byte[16];
            rng.GetBytes(salt);
            byte[] array;

            using (Aes aes = Aes.Create())
            {
                using (MemoryStream memoryStream = new())
                {
                    //Write salt and IV to stream prior to encryption - ST
                    memoryStream.Write(salt, 0, salt.Length);
                    memoryStream.Write(iv, 0, iv.Length);

                    //1234 is considered our pepper - the hard-coded number of mutations to use - ST
                    using Rfc2898DeriveBytes pdb = new(key, salt, 1234); 

                    aes.Key = pdb.GetBytes(32);
                    aes.IV = iv;
                    ICryptoTransform encryptor = aes.CreateEncryptor(aes.Key, aes.IV);
                    using (CryptoStream cryptoStream = new ((Stream)memoryStream, encryptor, CryptoStreamMode.Write))
                    {
                        using (StreamWriter streamWriter = new ((Stream)cryptoStream))
                        {
                            streamWriter.Write(dataToEncrypt);
                        }
                        array = memoryStream.ToArray();
                    }
                }
            }
            return Convert.ToBase64String(array);
        }

        public string Decrypt(string dataToDecrypt)
        {
            if (string.IsNullOrEmpty(key))
                throw new ArgumentNullException("EncryptionKey", "Please initialize your encryption key.");

            if (string.IsNullOrEmpty(dataToDecrypt))
                return string.Empty;

            byte[] iv = new byte[16];
            byte[] salt = new byte[16];

            using (Aes aes = Aes.Create())
            {
                var buffer = Convert.FromBase64String(dataToDecrypt);
                using (MemoryStream memoryStream = new(buffer))
                {
                    memoryStream.Read(salt, 0, salt.Length);
                    memoryStream.Read(iv, 0, iv.Length);

                    //1234 is considered our pepper - the hard-coded number of mutations to use - ST
                    using Rfc2898DeriveBytes pdb = new(key, salt, 1234); 

                    aes.Key = pdb.GetBytes(32);
                    aes.IV = iv;
                    ICryptoTransform decryptor = aes.CreateDecryptor(aes.Key, aes.IV);
                    using (CryptoStream cryptoStream = new ((Stream)memoryStream, decryptor, CryptoStreamMode.Read))
                    {
                        using (StreamReader streamReader = new ((Stream)cryptoStream))
                        {
                            return streamReader.ReadToEnd();
                        }
                    }
                }
            }
        }
    }
}
NinjaCross commented 1 year ago

Amazing suggestion, thanks @SeanTalley