How to speed up this c # filestream encryption method

I have an encryption method that is incredibly slow. It takes about 20 minutes to encrypt several hundred MB of data. Iโ€™m not sure that I am right. Any help, thoughts, advice would be greatly appreciated.

private void AES_Encrypt(string inputFile, string outputFile, byte[] passwordBytes, byte[] saltBytes) { FileStream fsCrypt = new FileStream(outputFile, FileMode.Create); RijndaelManaged AES = new RijndaelManaged(); AES.KeySize = 256; AES.BlockSize = 128; var key = new Rfc2898DeriveBytes(passwordBytes, saltBytes, 1000); AES.Key = key.GetBytes(AES.KeySize / 8); AES.IV = key.GetBytes(AES.BlockSize / 8); AES.Padding = PaddingMode.Zeros; AES.Mode = CipherMode.CBC; CryptoStream cs = new CryptoStream(fsCrypt, AES.CreateEncryptor(), CryptoStreamMode.Write); FileStream fsIn = new FileStream(inputFile, FileMode.Open); int data; while ((data = fsIn.ReadByte()) != -1) cs.WriteByte((byte)data); fsCrypt.Flush(); cs.Flush(); fsIn.Flush(); fsIn.Close(); cs.Close(); fsCrypt.Close(); } 

Thank you for your help!

+5
source share
3 answers

Although encryption can be slow, I would not expect this to be a problem. I suspect that byte byte IO is causing unnecessary overhead. The easiest way to fix this is with a sensible call to Stream.CopyTo - and while you are on it, you should use the using statements to properly clear it:

 private void AesEncrypt(string inputFile, string outputFile, byte[] passwordBytes, byte[] saltBytes) { var key = new Rfc2898DeriveBytes(passwordBytes, saltBytes, 1000); RijndaelManaged aes = new RijndaelManaged { KeySize = 256, BlockSize = 128, Key = key.GetBytes(AES.KeySize / 8), IV = key.GetBytes(AES.BlockSize / 8), Padding = PaddingMode.Zeros, Mode = CipherMode.CBC }; using (var output = File.Create(outputFile)) { using (var crypto = new CryptoStream(output, aes.CreateEncryptor(), CryptoStreamMode.Write)) { using (var input = File.OpenRead(inputFile)) { input.CopyTo(crypto); } } } } 

As noted in other answers, this is not a good way to generate IV. In general, I would rather use Rijndael.Create() instead of specifying RijndaelManaged - and you probably want to use the using statement for it as well.

+11
source

You read exactly one byte at a time. This creates a lot of overhead.

To speed up processing, start using more bytes at the same time or call the internal copy function:

 fsIn.CopyTo(cs); 

MSDN

+6
source

Reading one byte at a time is a terrible idea. Use the built-in Stream.CopyTo method:

 fsIn.CopyTo(cs); 

Also note that getting an IV from the same material from which you are extracting the key is bad practice and can lead to security vulnerabilities. In some cases, it may even allow an attacker to access plaintext. You must randomly generate an IV for each encryption operation.

+2
source

Source: https://habr.com/ru/post/1274826/


All Articles