Add progress bar using Cryptostream not with FileStream to Increase the speed of the Encryption

Diary Kely 1 Reputation point
2022-12-12T17:57:16.03+00:00

Hi everyone,
sorry, is it possible to use CryptoStream class with Progress bar directly when Encrypt file ?
Because, when i loop using fileStream.Read to increment the value for Pogress bar and write the file it takes a time, especially when the file is more than 2 MB.

This is my code:
Speed encryption without using filestream but no progress bar, i don't know where to put the background work propriety.

	public  byte[] AES_Encrypt(byte[] fileContent, byte[] mtpass, string ifile)  
	{					  
		byte[] salt_Bytes = new byte[] {10, 20, 30, 40, 50, 60, 70, 80};   
		RijndaelManaged AES = new RijndaelManaged();  
		AES.KeySize = 256;  
		AES.BlockSize = 128;  
		var key = new Rfc2898DeriveBytes(mtpass, salt_Bytes, 1000);  
		AES.Key = key.GetBytes(AES.KeySize / 8);  
		AES.IV = key.GetBytes(AES.BlockSize / 8);  
		AES.Mode = CipherMode.CBC;  
		AES.Padding = PaddingMode.Zeros;  

	//SPEED INCRYPTION WITHOUT PROGRESS BAR  
	  
		MemoryStream mem = new MemoryStream();  
		CryptoStream fich_crypt_mem = new CryptoStream(mem, AES.CreateEncryptor(), CryptoStreamMode.Write);  
		  
	//MAYBE HERE TO ADD THE CODE FOR CHANGE THE VALUE FOR PROGRESS BAR   
		fich_crypt_mem.Write(fileContent, 0, fileContent.Length);  
	  
		fich_crypt_mem.Close();  
		return  mem.ToArray();  
	}  

The code: using fileStream and Progress bar work fine, but slow encryption:

public byte[] AES_Encrypt(byte[] fileContent, byte[] mtpass, string ifile)
{
//AES KEY GENERATE(SAME)

// PROGRESS BAR WORK BUT ENCRYPTION SLOW  
	  
MemoryStream mem = new MemoryStream();  
CryptoStream fich_crypt_mem = new CryptoStream(mem, AES.CreateEncryptor(), CryptoStreamMode.Write);  
  
// USING FileStream TO CHANGE THE VALUE OF PROGRESS BAR AND WRITE THE ENCRYPT FILE  
FileStream fsIn = new FileStream(ifile, FileMode.Open);  

int data;  
  
double counter = 1;  
  
while ((data = fsIn.ReadByte()) != -1) //Loop FileStream.Read  
{  
	fich_crypt_mem.WriteByte((byte)data);  
  
	myBWorker.ReportProgress((int)((counter / fsIn.Length) * 100)); // progressbar using BackgroundWorker  
	counter++;  
}  

}

Thanks, and sorry for my English is not good.

Developer technologies | C#
{count} votes

1 answer

Sort by: Most helpful
  1. P a u l 10,761 Reputation points
    2022-12-12T19:25:12.437+00:00

    I'd assume it was because you're reading/writing bytes one at a time rather than reading a chunk of them all together into a buffer. It's quite inefficient, particularly for the synchronous ReadByte & WriteByte methods.

    You could look at reading/writing a sequence of bytes in one go (say 1KB?) and that will likely improve things. It would probably be a good idea to opt for the asynchronous versions of these methods too (i.e. ReadAsync instead of Read & WriteAsync instead of Write).

    Marc Gravell has added a concise example (of the synchronous method of doing this) to this SO post:
    https://stackoverflow.com/questions/2030847/best-way-to-read-a-large-file-into-a-byte-array-in-c#answer-2030971

    In this example you'd replace your double counter for a int totalBytesRead and before you report your progress event you would do totalBytesRead += bytesRead


Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.