private static bool removePadding = true; // can be set to false by HandleConfigurationArguments public static void Main(String[] args) { Console.WriteLine("~~ Padding Oracle Attack Demo ~~"); HandleConfigurationArguments(args); Console.WriteLine("Oracle response delay set to {0} ms.", oracle.OracleDelayMilliseconds); Console.WriteLine("\nEnter plaintext:"); string plaintext = Console.ReadLine(); byte[] encrypted = oracle.Encrypt(plaintext); var blocks = ByteUtils.SliceIntoBlocks(encrypted); Console.WriteLine("\nCiphertext blocks (base64):\n{0}", String.Join("\n", blocks.ConvertAll(block => Convert.ToBase64String(block)))); Console.WriteLine("\nPadding oracle attack results:"); Console.WriteLine("(first block cannot be decrypted)"); var stopwatch = new Stopwatch(); var lastBlockIndex = blocks.Count - 1; for (int blockIndex = 1; blockIndex <= lastBlockIndex; ++blockIndex) { stopwatch.Start(); var decrypted = decryptor.DecryptBlock(blocks[blockIndex], blocks[blockIndex - 1]); stopwatch.Stop(); if (removePadding && blockIndex == lastBlockIndex) { decrypted = PaddingUtils.GetPaddingRemoverFromMode(oracle.Padding).Invoke(decrypted); } var decryptedPlaintext = Encoding.UTF8.GetString(decrypted, 0, decrypted.Length); Console.WriteLine(decryptedPlaintext.Length > 0 ? decryptedPlaintext : "(padding-only block)"); } var decodedBlocksCount = blocks.Count - 1; Console.WriteLine("\nDecoded {0} blocks.", decodedBlocksCount); if (decodedBlocksCount > 0) { var timeElapsed = stopwatch.Elapsed; Console.WriteLine("Time elapsed: {0}, avg {1:0.000} s per block", timeElapsed.ToString(), timeElapsed.Divide(decodedBlocksCount).TotalMilliseconds / 1000); } }
public PaddingOracleDecryptor(RemoteServerMock oracle) { this.oracle = oracle; paddingValueProvider = PaddingUtils.GetPaddingValueProviderFromMode(oracle.Padding); }