Я пытаюсь создать метод шифрования AES, в котором один и тот же файл считывается и записывается одновременно.Другие коды, которые я прочитал, создают новый файл, я не хочу иметь новый файл.Другая зашифрованная строка соответствовала моему справочному выводу из отдельного вывода, за исключением того, что мой метод генерировал неверную последнюю строку в виде обычного текста плюс дополнительные байты.
Я попытался заменить аргумент FileStream CryptoStream и удалить fs.Seek () в строке 58, программа работает правильно и сгенерировал новый зашифрованный файл .aes для моего справочного вывода выше.
static void Main(string[] args)
{
AESCryptFile(@"C:\Users\user\Downloads\test.txt",
new byte[] { 0x13, 0x11, 0x7F, 0x08, 0x45, 0x2E, 0x96, 0x33 },
new byte[] { 0x13, 0x11, 0x7F, 0x08, 0x45, 0x2E, 0x96, 0x33 }, false);
Console.WriteLine("Done");
Console.ReadLine();
}
public async static void AESCryptFile
(string path, byte[] key, byte[] iv, bool encrypt)
{
// validation
if (path == null || !File.Exists(path))
throw new FileNotFoundException("Path does not exist");
if (key == null || key.Length == 0)
throw new ArgumentNullException("Password is null");
if (iv == null || iv.Length < 8)
throw new ArgumentException("IV is null or under 8 bytes long");
// in and out stream for files
FileStream fs = new FileStream
(path, FileMode.Open, FileAccess.ReadWrite, FileShare.None);
// initialize aes with safe hash and mode
RijndaelManaged algo = new RijndaelManaged();
Rfc2898DeriveBytes hashed = new Rfc2898DeriveBytes(key, iv, 25000);
algo.Key = hashed.GetBytes(32);
algo.IV = hashed.GetBytes(16);
algo.Padding = PaddingMode.PKCS7;
algo.Mode = CipherMode.CFB;
// mediator stream for cryptography
CryptoStream cs = new CryptoStream(fs,
encrypt ? algo.CreateEncryptor() : algo.CreateDecryptor(),
encrypt ? CryptoStreamMode.Write : CryptoStreamMode.Read);
// main file transfer and crypto
await Task.Run(
() => readCryptWrite(new FileInfo(path).Length, fs, cs, encrypt));
}
private static void readCryptWrite(long fileSize, FileStream fs,
CryptoStream cs, bool encrypt)
{
// 1 MB of buffer zone allocation
byte[] buffer = new byte[1048576];
int nextBlockSize;
long processedSize = 0;
// loop while there are more to read
while ((nextBlockSize = encrypt ? fs.Read(buffer, 0, buffer.Length) :
cs.Read(buffer, 0, buffer.Length)) > 0)
{
// set pointer back to last written space
fs.Seek(processedSize, SeekOrigin.Begin);
// write out to file
if (encrypt) cs.Write(buffer, 0, nextBlockSize);
else fs.Write(buffer, 0, nextBlockSize);
// set progress
processedSize = fs.Position;
SetProgress?.Invoke((int)((double)processedSize / fileSize * 100));
if (nextBlockSize != buffer.Length) break;
}
// close streams
cs.Clear();
cs.Close();
fs.Close();
}
Используемый мной ввод: Длинный английский файл