public static void BC() { Random r = new Random(); byte[] input = new byte[1 << 4]; byte[] key = new byte[1 << 4]; r.NextBytes(input); r.NextBytes(key); Console.WriteLine("Input:"); print(input); Console.WriteLine("Key:"); print(key); blockCipher Block = new blockCipher(input, key); Console.WriteLine("EN:"); print(Block.encrypt()); blockCipher Block2 = new blockCipher(Block.encrypt(), key); Console.WriteLine("DC:"); print(Block2.decrypt()); }
/// <summary> /// Decrypt a given source file and save it to a given target file. /// </summary> /// <param name="sourceFileName">The filename of the source file. Presumed to exist.</param> /// <param name="destinationFileName">The filename of the target file. Will be overwritten.</param> /// <param name="key">The key to decrypt with.</param> public static void StartDecryption(String sourceFileName, String destinationFileName, String key) { // Auxiliary variables int readPos = 0; // Reading position Int64 originalFileSize = 0; // Original file size Int64 remainingBody = 0; // Bytes left to read Int32 blockSize = 0; byte cipherMode = 0; byte cr = Convert.ToByte('\r'); byte lf = Convert.ToByte('\n'); byte[] initializationVector; char[] keyChars = key.ToCharArray(); int keyLength = Math.Max(key.Length, blockCipherEnDc.SIZE); byte[] keyBytes = new byte[keyLength]; for (var i = 0; i < keyLength; ++i) { if (i < key.Length) { keyBytes[i] = Convert.ToByte(keyChars[i]); } else { keyBytes[i] = 0; } } // Open read handle. Treat all files as binary. FileStream fr = File.OpenRead(sourceFileName); BinaryReader br = new BinaryReader(fr); // Open write handle. FileStream fw = File.OpenWrite(destinationFileName); BinaryWriter bw = new BinaryWriter(fw); // Read header // 1. Original filesize originalFileSize = br.ReadInt64(); readPos += sizeof(Int64); // 2. Block size blockSize = br.ReadInt32(); readPos += sizeof(Int32); // 3. Cipher mode cipherMode = br.ReadByte(); readPos += sizeof(byte); // 4. CRLF -- validate their existence if (br.ReadByte() != cr) { throw new Exception("Invalid ciphertext header."); } readPos += sizeof(byte); if (br.ReadByte() != lf) { throw new Exception("Invalid ciphertext header."); } readPos += sizeof(byte); // 5. Initialization vector initializationVector = br.ReadBytes(blockSize); readPos += blockSize; // 6. CRLF again -- validate their existence if (br.ReadByte() != cr) { throw new Exception("Invalid ciphertext header."); } readPos += sizeof(byte); if (br.ReadByte() != lf) { throw new Exception("Invalid ciphertext header."); } readPos += sizeof(byte); // We're done with the header, we can now proceed to the body. remainingBody = originalFileSize; byte[] previousBlock = initializationVector; while (readPos < fr.Length) { byte[] cipherBuffer = br.ReadBytes(blockSize); byte[] toWrite = new byte[blockSize]; byte[] plainBuffer; byte[] preXor; blockCipher Cipher; // Decrypt the buffer and write to destination file switch (cipherMode) { case ECB: Cipher = new blockCipher(cipherBuffer, keyBytes); plainBuffer = Cipher.decrypt(); toWrite = plainBuffer; break; case CBC: Cipher = new blockCipher(cipherBuffer, keyBytes); preXor = Cipher.decrypt(); plainBuffer = XorByteArray(preXor, previousBlock); toWrite = plainBuffer; previousBlock = cipherBuffer; break; case CFB: Cipher = new blockCipher(previousBlock, keyBytes); preXor = Cipher.encrypt(); plainBuffer = XorByteArray(preXor, cipherBuffer); toWrite = plainBuffer; previousBlock = cipherBuffer; break; case OFB: Cipher = new blockCipher(previousBlock, keyBytes); preXor = Cipher.encrypt(); plainBuffer = XorByteArray(preXor, cipherBuffer); toWrite = plainBuffer; previousBlock = preXor; break; default: break; } if (remainingBody < blockSize) { byte[] writeBuffer = new byte[remainingBody]; Array.Copy(toWrite, writeBuffer, (int)remainingBody); bw.Write(writeBuffer); } else { bw.Write(toWrite); } readPos += blockSize; remainingBody -= blockSize; } // Mode is read from the header of the file // Close write handle bw.Close(); fw.Close(); // Close read handle br.Close(); fr.Close(); }