private void process(int action) { //Encrypt/Decrypt Stream try { if (InputStream == null || InputStream.Length == 0) { GuiLogMessage("No input data, aborting now", NotificationLevel.Error); return; } SymmetricAlgorithm p_alg = null; if (settings.CryptoAlgorithm == 1) { p_alg = new RijndaelManaged(); } else { p_alg = new AesCryptoServiceProvider(); } ConfigureAlg(p_alg); ICryptoTransform p_encryptor = null; switch (action) { case 0: p_encryptor = p_alg.CreateEncryptor(); break; case 1: p_encryptor = p_alg.CreateDecryptor(); break; } outputStreamWriter = new CStreamWriter(); ICrypToolStream inputdata = InputStream; string mode = action == 0 ? "encryption" : "decryption"; long inbytes, outbytes; //GuiLogMessage("Starting " + mode + " [Keysize=" + p_alg.KeySize.ToString() + " Bits, Blocksize=" + p_alg.BlockSize.ToString() + " Bits]", NotificationLevel.Info); DateTime startTime = DateTime.Now; // special handling of OFB mode, as it's not available for AES in .Net if (settings.Mode == 3) // OFB - bei OFB ist encrypt = decrypt, daher keine Fallunterscheidung { if (action == 0) { inputdata = BlockCipherHelper.AppendPadding(InputStream, settings.padmap[settings.Padding], p_alg.BlockSize / 8); } ICryptoTransform encrypt = p_alg.CreateEncryptor(p_alg.Key, p_alg.IV); byte[] IV = new byte[p_alg.IV.Length]; Array.Copy(p_alg.IV, IV, p_alg.IV.Length); byte[] tmpInput = BlockCipherHelper.StreamToByteArray(inputdata); byte[] outputData = new byte[tmpInput.Length]; for (int pos = 0; pos <= tmpInput.Length - encrypt.InputBlockSize;) { int l = encrypt.TransformBlock(IV, 0, encrypt.InputBlockSize, outputData, pos); for (int i = 0; i < l; i++) { IV[i] = outputData[pos + i]; outputData[pos + i] ^= tmpInput[pos + i]; } pos += l; } int validBytes = (int)inputdata.Length; if (action == 1) { validBytes = BlockCipherHelper.StripPadding(outputData, validBytes, settings.padmap[settings.Padding], p_alg.BlockSize / 8); } encrypt.Dispose(); outputStreamWriter.Write(outputData, 0, validBytes); inbytes = inputdata.Length; } else if (settings.Mode == 4) { if (action == 0) { inputdata = BlockCipherHelper.AppendPadding(InputStream, settings.padmap[settings.Padding], p_alg.BlockSize / 8); } byte[] tmpInput = BlockCipherHelper.StreamToByteArray(inputdata); var cipher = new AesEngine(); var eaxCipher = new EaxBlockCipher(cipher); var keyParameter = new KeyParameter(p_alg.Key); var parameter = new ParametersWithIV(keyParameter, p_alg.IV); eaxCipher.Init((action == 0) ? true : false, parameter); byte[] datOut = new byte[eaxCipher.GetOutputSize(tmpInput.Length)]; int outOff = eaxCipher.ProcessBytes(tmpInput, 0, tmpInput.Length, datOut, 0); outOff += eaxCipher.DoFinal(datOut, outOff); int validBytes = (int)eaxCipher.GetOutputSize(tmpInput.Length); if (action == 1) { validBytes = BlockCipherHelper.StripPadding(datOut, validBytes, settings.padmap[settings.Padding], p_alg.BlockSize / 8); } outputStreamWriter.Write(datOut, 0, validBytes); inbytes = inputdata.Length; } else { // append 1-0 padding (special handling, as it's not present in System.Security.Cryptography.PaddingMode) if (action == 0 && settings.Padding == 5) { inputdata = BlockCipherHelper.AppendPadding(InputStream, BlockCipherHelper.PaddingType.OneZeros, p_alg.BlockSize / 8); } CStreamReader reader = inputdata.CreateReader(); p_crypto_stream = new CryptoStream(reader, p_encryptor, CryptoStreamMode.Read); byte[] buffer = new byte[p_alg.BlockSize / 8]; int bytesRead; int position = 0; while ((bytesRead = p_crypto_stream.Read(buffer, 0, buffer.Length)) > 0 && !stop) { // remove 1-0 padding (special handling, as it's not present in System.Security.Cryptography.PaddingMode) if (action == 1 && settings.Padding == 5 && reader.Position == reader.Length) { bytesRead = BlockCipherHelper.StripPadding(buffer, bytesRead, BlockCipherHelper.PaddingType.OneZeros, buffer.Length); } outputStreamWriter.Write(buffer, 0, bytesRead); if ((int)(reader.Position * 100 / reader.Length) > position) { position = (int)(reader.Position * 100 / reader.Length); ProgressChanged(reader.Position, reader.Length); } } p_crypto_stream.Flush(); inbytes = reader.Length; } outbytes = outputStreamWriter.Length; DateTime stopTime = DateTime.Now; TimeSpan duration = stopTime - startTime; // (outputStream as CrypToolStream).FinishWrite(); if (!stop) { mode = action == 0 ? "Encryption" : "Decryption"; //GuiLogMessage(mode + " complete! (in: " + inbytes + " bytes, out: " + outbytes + " bytes)", NotificationLevel.Info); //GuiLogMessage("Time used: " + duration.ToString(), NotificationLevel.Debug); outputStreamWriter.Close(); OnPropertyChanged("OutputStream"); } if (stop) { outputStreamWriter.Close(); GuiLogMessage("Aborted!", NotificationLevel.Info); } } catch (CryptographicException cryptographicException) { // TODO: For an unknown reason p_crypto_stream cannot be closed after exception. // Trying so makes p_crypto_stream throw the same exception again. So in Dispose // the error messages will be doubled. // As a workaround we set p_crypto_stream to null here. p_crypto_stream = null; string msg = cryptographicException.Message; // Workaround for misleading german error message if (msg == "Die Zeichenabstände sind ungültig und können nicht entfernt werden.") { msg = "Das Padding ist ungültig und kann nicht entfernt werden."; } GuiLogMessage(msg, NotificationLevel.Error); } catch (Exception exception) { GuiLogMessage(exception.Message, NotificationLevel.Error); } finally { ProgressChanged(1, 1); } }
private void process(int action) { //Encrypt/Decrypt Stream try { if (InputStream == null || InputStream.Length == 0) { GuiLogMessage("No input data, aborting now", NotificationLevel.Error); return; } ICryptoTransform p_encryptor; SymmetricAlgorithm p_alg = null; if (settings.TripleDES) { p_alg = new TripleDESCryptoServiceProvider(); } else { p_alg = new DESCryptoServiceProvider(); } ConfigureAlg(p_alg); outputStreamWriter = new CStreamWriter(); ICryptoolStream inputdata = InputStream; // append 1-0 padding (special handling, as it's not present in System.Security.Cryptography.PaddingMode) if (action == 0) { inputdata = BlockCipherHelper.AppendPadding(InputStream, settings.padmap[settings.Padding], p_alg.BlockSize / 8); } CStreamReader reader = inputdata.CreateReader(); //GuiLogMessage("Starting encryption [Keysize=" + p_alg.KeySize.ToString() + " Bits, Blocksize=" + p_alg.BlockSize.ToString() + " Bits]", NotificationLevel.Info); DateTime startTime = DateTime.Now; // special handling of OFB mode, as it's not available for DES in .Net if (settings.Mode == 3) // OFB - bei OFB ist encrypt = decrypt, daher keine Fallunterscheidung { try { p_encryptor = p_alg.CreateEncryptor(p_alg.Key, p_alg.IV); } catch { //dirty hack to allow weak keys: MethodInfo mi = p_alg.GetType().GetMethod("_NewEncryptor", BindingFlags.NonPublic | BindingFlags.Instance); object[] Par = { p_alg.Key, p_alg.Mode, p_alg.IV, p_alg.FeedbackSize, 0 }; p_encryptor = mi.Invoke(p_alg, Par) as ICryptoTransform; } byte[] IV = new byte[p_alg.IV.Length]; Array.Copy(p_alg.IV, IV, p_alg.IV.Length); byte[] tmpInput = BlockCipherHelper.StreamToByteArray(inputdata); byte[] outputData = new byte[tmpInput.Length]; for (int pos = 0; pos <= tmpInput.Length - p_encryptor.InputBlockSize;) { int l = p_encryptor.TransformBlock(IV, 0, p_encryptor.InputBlockSize, outputData, pos); for (int i = 0; i < l; i++) { IV[i] = outputData[pos + i]; outputData[pos + i] ^= tmpInput[pos + i]; } pos += l; } outputStreamWriter.Write(outputData); } else { try { p_encryptor = (action == 0) ? p_alg.CreateEncryptor() : p_alg.CreateDecryptor(); } catch { //dirty hack to allow weak keys: MethodInfo mi = (action == 0) ? p_alg.GetType().GetMethod("_NewEncryptor", BindingFlags.NonPublic | BindingFlags.Instance) : p_alg.GetType().GetMethod("_NewDecryptor", BindingFlags.NonPublic | BindingFlags.Instance);; object[] par = { p_alg.Key, p_alg.Mode, p_alg.IV, p_alg.FeedbackSize, 0 }; p_encryptor = mi.Invoke(p_alg, par) as ICryptoTransform; } p_crypto_stream = new CryptoStream((Stream)reader, p_encryptor, CryptoStreamMode.Read); byte[] buffer = new byte[p_alg.BlockSize / 8]; int bytesRead; while ((bytesRead = p_crypto_stream.Read(buffer, 0, buffer.Length)) > 0 && !stop) { //// remove 1-0 padding (special handling, as it's not present in System.Security.Cryptography.PaddingMode) //if (action == 1 && settings.Padding == 5 && reader.Position == reader.Length) // bytesRead = BlockCipherHelper.StripPadding(buffer, bytesRead, BlockCipherHelper.PaddingType.OneZeros, buffer.Length); outputStreamWriter.Write(buffer, 0, bytesRead); } p_crypto_stream.Flush(); } outputStreamWriter.Close(); //DateTime stopTime = DateTime.Now; //TimeSpan duration = stopTime - startTime; if (action == 1) { outputStreamWriter = BlockCipherHelper.StripPadding(outputStreamWriter, settings.padmap[settings.Padding], p_alg.BlockSize / 8) as CStreamWriter; } if (!stop) { //GuiLogMessage("Encryption complete! (in: " + reader.Length.ToString() + " bytes, out: " + outputStreamWriter.Length.ToString() + " bytes)", NotificationLevel.Info); //GuiLogMessage("Time used: " + duration.ToString(), NotificationLevel.Debug); OnPropertyChanged("OutputStream"); } else { GuiLogMessage("Aborted!", NotificationLevel.Info); } } catch (CryptographicException cryptographicException) { p_crypto_stream = null; string msg = cryptographicException.Message; // Workaround for misleading padding error message if (msg.StartsWith("Ungültige Daten")) { msg = "Das Padding ist ungültig und kann nicht entfernt werden."; } GuiLogMessage(msg, NotificationLevel.Error); } catch (Exception exception) { GuiLogMessage(exception.Message, NotificationLevel.Error); } finally { ProgressChanged(1, 1); } }
private void Crypt() { try { ICryptoTransform p_encryptor; SymmetricAlgorithm p_alg = TwofishManaged.Create(); ConfigureAlg(p_alg); outputStreamWriter = new CStreamWriter(); ICryptoolStream inputdata = InputStream; if (settings.Action == 0) { inputdata = BlockCipherHelper.AppendPadding(InputStream, settings.padmap[settings.Padding], p_alg.BlockSize / 8); } CStreamReader reader = inputdata.CreateReader(); byte[] tmpInput = BlockCipherHelper.StreamToByteArray(inputdata); byte[] outputData = new byte[tmpInput.Length]; byte[] IV = new byte[p_alg.IV.Length]; Array.Copy(p_alg.IV, IV, p_alg.IV.Length); int bs = p_alg.BlockSize >> 3; if (settings.Mode == 0) // ECB { p_encryptor = (settings.Action == 0) ? p_alg.CreateEncryptor(p_alg.Key, p_alg.IV) : p_alg.CreateDecryptor(p_alg.Key, p_alg.IV); for (int pos = 0; pos < tmpInput.Length; pos += bs) { p_encryptor.TransformBlock(tmpInput, pos, bs, outputData, pos); } } else if (settings.Mode == 1) // CBC { if (settings.Action == 0) { p_encryptor = p_alg.CreateEncryptor(p_alg.Key, p_alg.IV); for (int pos = 0; pos < tmpInput.Length; pos += bs) { for (int i = 0; i < bs; i++) { tmpInput[pos + i] ^= IV[i]; } p_encryptor.TransformBlock(tmpInput, pos, bs, outputData, pos); for (int i = 0; i < bs; i++) { IV[i] = outputData[pos + i]; } } } else { p_encryptor = p_alg.CreateDecryptor(p_alg.Key, p_alg.IV); for (int pos = 0; pos < tmpInput.Length; pos += bs) { p_encryptor.TransformBlock(tmpInput, pos, bs, outputData, pos); for (int i = 0; i < bs; i++) { outputData[pos + i] ^= IV[i]; IV[i] = tmpInput[pos + i]; } } } } else if (settings.Mode == 2) // CFB { p_encryptor = p_alg.CreateEncryptor(p_alg.Key, p_alg.IV); if (settings.Action == 0) { for (int pos = 0; pos < tmpInput.Length; pos += bs) { p_encryptor.TransformBlock(IV, 0, p_encryptor.InputBlockSize, outputData, pos); for (int i = 0; i < bs; i++) { outputData[pos + i] ^= tmpInput[pos + i]; IV[i] = outputData[pos + i]; } } } else { for (int pos = 0; pos < tmpInput.Length; pos += bs) { p_encryptor.TransformBlock(IV, 0, p_encryptor.InputBlockSize, outputData, pos); for (int i = 0; i < bs; i++) { IV[i] = tmpInput[pos + i]; outputData[pos + i] ^= tmpInput[pos + i]; } } } } else if (settings.Mode == 3) // OFB { p_encryptor = p_alg.CreateEncryptor(p_alg.Key, p_alg.IV); for (int pos = 0; pos < tmpInput.Length; pos += bs) { p_encryptor.TransformBlock(IV, 0, p_encryptor.InputBlockSize, outputData, pos); for (int i = 0; i < bs; i++) { IV[i] = outputData[pos + i]; outputData[pos + i] ^= tmpInput[pos + i]; } } } outputStreamWriter.Write(outputData); //if( p_encryptor!=null ) p_encryptor.Dispose(); outputStreamWriter.Close(); if (settings.Action == 1) { outputStreamWriter = BlockCipherHelper.StripPadding(outputStreamWriter, settings.padmap[settings.Padding], p_alg.BlockSize / 8) as CStreamWriter; } OnPropertyChanged("OutputStream"); } catch (CryptographicException cryptographicException) { // TODO: For an unknown reason p_crypto_stream can not be closed after exception. // Trying so makes p_crypto_stream throw the same exception again. So in Dispose // the error messages will be doubled. // As a workaround we set p_crypto_stream to null here. p_crypto_stream = null; GuiLogMessage(cryptographicException.Message, NotificationLevel.Error); } catch (Exception exception) { GuiLogMessage(exception.Message, NotificationLevel.Error); } }
private void process(int action) { //Encrypt/Decrypt Stream try { if (inputStream == null || inputStream.Length == 0) { GuiLogMessage("No input data, aborting now", NotificationLevel.Error); return; } ICryptoTransform p_encryptor; SymmetricAlgorithm p_alg = new RC2CryptoServiceProvider(); ConfigureAlg(p_alg); outputStreamWriter = new CStreamWriter(); ICryptoolStream inputdata = InputStream; if (action == 0) { inputdata = BlockCipherHelper.AppendPadding(InputStream, settings.padmap[settings.Padding], p_alg.BlockSize / 8); } CStreamReader reader = inputdata.CreateReader(); GuiLogMessage("Starting " + ((settings.Action == 0)?"encryption":"decryption") + " [Keysize=" + p_alg.KeySize.ToString() + " Bits, Blocksize=" + p_alg.BlockSize.ToString() + " Bits]", NotificationLevel.Info); DateTime startTime = DateTime.Now; // special handling of OFB mode, as it's not available for RC2 in .Net if (settings.Mode == 3) // OFB - bei OFB ist encrypt = decrypt, daher keine Fallunterscheidung { p_encryptor = p_alg.CreateEncryptor(p_alg.Key, p_alg.IV); byte[] IV = new byte[p_alg.IV.Length]; Array.Copy(p_alg.IV, IV, p_alg.IV.Length); byte[] tmpInput = BlockCipherHelper.StreamToByteArray(inputdata); byte[] outputData = new byte[tmpInput.Length]; for (int pos = 0; pos <= tmpInput.Length - p_encryptor.InputBlockSize;) { int l = p_encryptor.TransformBlock(IV, 0, p_encryptor.InputBlockSize, outputData, pos); for (int i = 0; i < l; i++) { IV[i] = outputData[pos + i]; outputData[pos + i] ^= tmpInput[pos + i]; } pos += l; } outputStreamWriter.Write(outputData); } else { p_encryptor = (action == 0) ? p_alg.CreateEncryptor() : p_alg.CreateDecryptor(); p_crypto_stream = new CryptoStream((Stream)reader, p_encryptor, CryptoStreamMode.Read); byte[] buffer = new byte[p_alg.BlockSize / 8]; int bytesRead; while ((bytesRead = p_crypto_stream.Read(buffer, 0, buffer.Length)) > 0 && !stop) { outputStreamWriter.Write(buffer, 0, bytesRead); } p_crypto_stream.Flush(); } outputStreamWriter.Close(); DateTime stopTime = DateTime.Now; TimeSpan duration = stopTime - startTime; if (action == 1) { outputStreamWriter = BlockCipherHelper.StripPadding(outputStreamWriter, settings.padmap[settings.Padding], p_alg.BlockSize / 8) as CStreamWriter; } if (!stop) { GuiLogMessage(((settings.Action == 0) ? "Encryption" : "Decryption") + " complete! (in: " + InputStream.Length + " bytes, out: " + outputStreamWriter.Length + " bytes)", NotificationLevel.Info); GuiLogMessage("Time used: " + duration, NotificationLevel.Debug); OnPropertyChanged("OutputStream"); } else { GuiLogMessage("Aborted!", NotificationLevel.Info); } } catch (CryptographicException cryptographicException) { // TODO: For an unknown reason p_crypto_stream can not be closed after exception. // Trying so makes p_crypto_stream throw the same exception again. So in Dispose // the error messages will be doubled. // As a workaround we set p_crypto_stream to null here. p_crypto_stream = null; GuiLogMessage(cryptographicException.Message, NotificationLevel.Error); } catch (Exception exception) { GuiLogMessage(exception.Message, NotificationLevel.Error); } finally { ProgressChanged(1, 1); } }