public void TestSwap() { CStreamWriter writer = new CStreamWriter(); // fill buffer with Length-1 bytes writer.Write(LongData); Assert.AreEqual(LongData.Length, writer.Position); Assert.IsFalse(writer.IsSwapped); // fill last byte writer.WriteByte(5); Assert.AreEqual(LongData.Length + 1, writer.Position); Assert.IsFalse(writer.IsSwapped); // write one byte more, assert swap writer.WriteByte(10); Assert.AreEqual(LongData.Length + 2, writer.Position); Assert.IsTrue(writer.IsSwapped); }
public void Execute() { try { // this is for localization ResourceManager resourceManager = new ResourceManager("Cryptool.RC4.Properties.Resources", GetType().Assembly); // make sure we have a valid data input if (inputData == null) { GuiLogMessage(resourceManager.GetString("ErrorInputDataNotProvided"), NotificationLevel.Error); return; } // make sure we have a valid key input if (inputKey == null) { GuiLogMessage(resourceManager.GetString("ErrorInputKeyNotProvided"), NotificationLevel.Error); return; } byte[] key = ToByteArray(inputKey); // make sure the input key is within the desired range if ((key.Length < 5 || key.Length > 256)) { GuiLogMessage(resourceManager.GetString("ErrorInputKeyInvalidLength"), NotificationLevel.Error); return; } // now execute the actual encryption using (CStreamReader reader = inputData.CreateReader()) { // create the output stream outputStreamWriter = new CStreamWriter(); // some variables int i = 0; int j = 0; // create the sbox byte[] sbox = new byte[256]; // initialize the sbox sequentially for (i = 0; i < 256; i++) { sbox[i] = (byte)(i); } // re-align the sbox (and incorporate the key) j = 0; for (i = 0; i < 256; i++) { j = (j + sbox[i] + key[i % key.Length]) % 256; byte sboxOld = sbox[i]; sbox[i] = sbox[j]; sbox[j] = sboxOld; } // process the input data using the modified sbox int position = 0; DateTime startTime = DateTime.Now; // some inits i = 0; j = 0; long bytesRead = 0; const long blockSize = 256; byte[] buffer = new byte[blockSize]; while ((bytesRead = reader.Read(buffer, 0, buffer.Length)) > 0 && !stop) { for (long n = 0; n < bytesRead; n++) { i = (i + 1) % 256; j = (j + sbox[i]) % 256; byte sboxOld = sbox[i]; sbox[i] = sbox[j]; sbox[j] = sboxOld; byte sboxRandom = sbox[(sbox[i] + sbox[j]) % 256]; byte cipherByte = (byte)(sboxRandom ^ buffer[n]); outputStreamWriter.WriteByte(cipherByte); } if ((int)(reader.Position * 100 / reader.Length) > position) { position = (int)(reader.Position * 100 / reader.Length); ProgressChanged(reader.Position, reader.Length); } } outputStreamWriter.Close(); // dump status information DateTime stopTime = DateTime.Now; TimeSpan duration = stopTime - startTime; 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"); } if (stop) { GuiLogMessage("Aborted!", NotificationLevel.Info); } } } catch (CryptographicException cryptographicException) { GuiLogMessage(cryptographicException.Message, NotificationLevel.Error); } catch (Exception exception) { GuiLogMessage(exception.Message, NotificationLevel.Error); } finally { ProgressChanged(1, 1); } }
private void Encrypt() { int length = settings.BlockKeyLen, bytesRead = 0; int roundMax = (int)(inputStreamReader.Length / length) + 1; List <byte> xor = new List <byte>(); List <byte> index = new List <byte>(); List <byte> ciphertext = new List <byte>(); byte[] plaintext = new byte[length]; matrixKey = new byte[passwordBytes.Length]; Buffer.BlockCopy(passwordBytes, 0, matrixKey, 0, passwordBytes.Length); int round = 1; while ((bytesRead = inputStreamReader.ReadFully(plaintext)) > 0) { if (bytesRead < length) { // in der letzten Runde Padding durch hinzufügen von Leerzeichen bis der Puffer voll ist for (int i = bytesRead; i < plaintext.Length; i++) { plaintext[i] = 0x20; } } // Schlüssel generieren Generator(round); // Verschlüsseln // 1. Klartext XOR Blockschlüssel for (int i = 0; i < length; i++) { xor.Add((byte)(plaintext[i] ^ blockKey[i])); } // bit conversation int puffer = 0; int bitCount = 0; for (int i = 0; i < length; i++) { puffer <<= 8; // mache für die nächsten 8 Bits Platz puffer |= xor[i]; // schreibe die nächsten 8 Bits in den Puffer bitCount += 8; // bitCount als Zähler für die Bits im Puffer, erhöhe um 8 index.Add((byte)(puffer >> (bitCount - 7) & 0x7F)); // lies die obersten 7 Bits aus bitCount -= 7; // verringere um 7, da 7 Bits ausgelesen wurden // aus Performancegründen werden die gelesenen Bits nicht gelöscht if (bitCount == 7) { index.Add((byte)(puffer & 0x7F)); // haben sich 7 Bits angesammelt, so ließ sie aus bitCount = 0; // 7 Bits gelesen, 7 - 7 = 0 } } switch (bitCount) { case 1: index.Add((byte)(puffer & 0x01)); break; case 2: index.Add((byte)(puffer & 0x03)); break; case 3: index.Add((byte)(puffer & 0x07)); break; case 4: index.Add((byte)(puffer & 0x0F)); break; case 5: index.Add((byte)(puffer & 0x1F)); break; case 6: index.Add((byte)(puffer & 0x3F)); break; default: break; } // Abbildung auf Chiffre-Alphabet for (int i = 0; i < index.Count; i++) { outputStreamWriter.WriteByte(cipherChars[index[i]]); } // Debugdaten schreiben if (settings.Debug) { WriteDebug("\r\n\r\nplaintext (hex): \r\n "); foreach (byte b in plaintext) { WriteDebug(String.Format(" {0:X2}", b)); } WriteDebug("\r\n\r\nplaintext xor block key (hex): \r\n "); xor.ForEach(delegate(byte b) { WriteDebug(String.Format(" {0:X2}", b)); }); WriteDebug("\r\n\r\nindex: \r\n "); index.ForEach(delegate(byte b) { WriteDebug(String.Format(" {0}", b)); }); WriteDebug("\r\n\r\nciphertext (hex): \r\n "); CStreamReader reader = outputStreamWriter.CreateReader(); int start = settings.BlockKeyLen * (round - 1); reader.Seek(start, SeekOrigin.Begin); for (int i = 0; i < index.Count; i++) { WriteDebug(String.Format(" {0:X2}", (byte)reader.ReadByte())); } WriteDebug("\r\n\r\n>>>>>>>>>> END OF ROUND <<<<<<<<<<\r\n\r\n\r\n"); } // Vorbereitungen für die nächste Runde cipherChars.Clear(); blockKey.Clear(); xor.Clear(); index.Clear(); if (stop) { break; } roundMax = (int)(inputStreamReader.Length / length) + 1; ProgressChanged(round, roundMax); round++; } }