/// <summary> /// Самообновление ключа /// </summary> private void RefreshKey() { // Создаем сущность, позволяющую шифровать потоки var streamCryptoWrapper = new StreamCryptoWrapper(); // Инициализируем сущность для шифрования хешем // от текущего ключа (неявно - внутренняя механика) streamCryptoWrapper.Initialize(BitmapKey); // Входной поток формируем на основе массива ключа... Stream msInput = new MemoryStream(BitmapKey); //...выходной поток изначально пуст... Stream msOutput = new MemoryStream(); //...но его оснащаем механизмом шифрования... Stream csOutput = streamCryptoWrapper.WrapStream(msOutput, true); // Процесс шифрования/расшифровки происходит прозрачно msInput.CopyTo(csOutput); ((CryptoStream)csOutput).FlushFinalBlock(); // После шифрования закрываем поток-источник,... msInput.Close(); //...сбрасываем буфер на зашифрованном потоке... csOutput.Flush(); msOutput.Flush(); //...и как завершение шифрования - деинициализируем криптовраппер streamCryptoWrapper.Clear(); // Готовим ключ к обновлению (в смысле размера) if(BitmapKey.Length != msOutput.Length) { CryforceUtilities.ClearArray(BitmapKey); BitmapKey = new byte[msOutput.Length]; } // Теперь результаты шифрования нужно перенести в массив ключа msOutput.Seek(0, SeekOrigin.Begin); msOutput.Read(BitmapKey, 0, BitmapKey.Length); csOutput.Close(); // Обновили ключ - сбросили индекс BitmapKeyIdx = 0; }
/// <summary> /// Шифрование по алгоритму Rijndael-256 /// </summary> /// <param name="inputStream">Входной поток.</param> /// <param name="key">Ключ для первого прохода шифрования.</param> /// <param name="outputStream">Выходной поток.</param> /// <param name="encryptionMode">Используется шифрование?</param> /// <param name="iterations">Количество итераций хеширования пароля.</param> public void SingleRijndael(Stream inputStream, byte[] key, Stream outputStream, bool encryptionMode, int iterations = 1) { if(!inputStream.CanSeek) { throw new Exception("Cryforce::SingleRijndael() ==> Input stream can't seek!"); } var streamCryptoWrapper = new StreamCryptoWrapper(); streamCryptoWrapper.Initialize(key, iterations); Stream inputStreamAtLevel0 = encryptionMode ? inputStream : streamCryptoWrapper.WrapStream(inputStream, false); Stream outputStreamAtLevel0 = encryptionMode ? streamCryptoWrapper.WrapStream(outputStream, true) : outputStream; inputStreamAtLevel0.SafeSeekBegin(); outputStreamAtLevel0.SafeSeekBegin(); // Процесс шифрования/расшифровки происходит прозрачно, во время чтения из зашифрованного потока или записи в зашифрованный // Размер буфера при копировании выбираем таким, чтобы обеспечить вывод каждого процента long dataSize = inputStream.Length; var bufferSize = (int)(dataSize / 100); CryforceUtilities.StreamCopy(ProgressChanged, inputStreamAtLevel0, outputStreamAtLevel0, dataSize, bufferSize); if(outputStreamAtLevel0 is CryptoStream) { ((CryptoStream)outputStreamAtLevel0).FlushFinalBlock(); } outputStreamAtLevel0.Flush(); // Если выходной поток первого уровня является криптографической оберткой над другим потоком - // нужно получить базовый поток для дальнейшей работы if(outputStreamAtLevel0 is CryptoStream) { outputStreamAtLevel0 = outputStream; } inputStreamAtLevel0.SafeSeekBegin(); outputStreamAtLevel0.SafeSeekBegin(); //...и как завершение шифрования - деинициализируем криптовраппер streamCryptoWrapper.Clear(); if(ProgressChanged != null) { ProgressChanged(null, new EventArgsGeneric<ProgressChangedArg>(new ProgressChangedArg("Rijndael-256", 100))); } }