11using System ;
22using System . Diagnostics ;
33using System . Security . Cryptography ;
4+ using System . Text ;
45using Mono . Options ;
56
67namespace Padding_Oracle_Attack
@@ -9,21 +10,22 @@ class PaddingOracleAttack
910 {
1011 // change the padding used by the oracle below (decryptor uses the same as the server/oracle)
1112 private const PaddingMode paddingMode = PaddingMode . PKCS7 ;
12- private static RemoteServerMock server = new RemoteServerMock ( paddingMode ) ;
13- private static PaddingOracleDecryptor decryptor = new PaddingOracleDecryptor ( server ) ;
13+ private static RemoteServerMock oracle = new RemoteServerMock ( paddingMode ) ;
14+ private static PaddingOracleDecryptor decryptor = new PaddingOracleDecryptor ( oracle ) ;
15+ private static bool removePadding = true ; // can be set to false by HandleConfigurationArguments
1416
1517 public static void Main ( String [ ] args )
1618 {
1719 Console . WriteLine ( "~~ Padding Oracle Attack Demo ~~" ) ;
1820
1921 HandleConfigurationArguments ( args ) ;
2022
21- Console . WriteLine ( "Oracle response delay set to {0} ms." , server . OracleDelayMilliseconds ) ;
23+ Console . WriteLine ( "Oracle response delay set to {0} ms." , oracle . OracleDelayMilliseconds ) ;
2224
2325 Console . WriteLine ( "\n Enter plaintext:" ) ;
2426 string plaintext = Console . ReadLine ( ) ;
2527
26- byte [ ] encrypted = server . Encrypt ( plaintext ) ;
28+ byte [ ] encrypted = oracle . Encrypt ( plaintext ) ;
2729 var blocks = ByteUtils . SliceIntoBlocks ( encrypted ) ;
2830
2931 Console . WriteLine ( "\n Ciphertext blocks (base64):\n {0}" , String . Join ( "\n " , blocks . ConvertAll ( block => Convert . ToBase64String ( block ) ) ) ) ;
@@ -33,15 +35,22 @@ public static void Main(String[] args)
3335
3436 var stopwatch = new Stopwatch ( ) ;
3537
36- for ( int blockIndex = 1 ; blockIndex < blocks . Count ; ++ blockIndex )
38+ var lastBlockIndex = blocks . Count - 1 ;
39+ for ( int blockIndex = 1 ; blockIndex <= lastBlockIndex ; ++ blockIndex )
3740 {
3841 stopwatch . Start ( ) ;
3942
40- string decryptedPlaintext = decryptor . DecryptBlock ( blocks [ blockIndex ] , blocks [ blockIndex - 1 ] ) ;
43+ var decrypted = decryptor . DecryptBlock ( blocks [ blockIndex ] , blocks [ blockIndex - 1 ] ) ;
4144
4245 stopwatch . Stop ( ) ;
4346
44- Console . WriteLine ( decryptedPlaintext [ 0 ] != 16 ? decryptedPlaintext : "(padding-only block)" ) ;
47+ if ( removePadding && blockIndex == lastBlockIndex )
48+ {
49+ decrypted = PaddingUtils . GetPaddingRemoverFromMode ( oracle . Padding ) . Invoke ( decrypted ) ;
50+ }
51+
52+ var decryptedPlaintext = Encoding . UTF8 . GetString ( decrypted , 0 , decrypted . Length ) ;
53+ Console . WriteLine ( decryptedPlaintext . Length > 0 ? decryptedPlaintext : "(padding-only block)" ) ;
4554 }
4655
4756 var decodedBlocksCount = blocks . Count - 1 ;
@@ -57,7 +66,8 @@ public static void Main(String[] args)
5766 private static void HandleConfigurationArguments ( String [ ] args )
5867 {
5968 OptionSet arguments = new OptionSet ( ) ;
60- arguments . Add ( "d|delay=" , "oracle delay in milliseconds for each padding request" , ( uint d ) => server . OracleDelayMilliseconds = d ) ;
69+ arguments . Add ( "d|delay=" , "oracle delay in milliseconds for each padding request" , ( uint d ) => oracle . OracleDelayMilliseconds = d ) ;
70+ arguments . Add ( "p|preserve-padding" , "don't remove padding from decoded string" , _ => removePadding = false ) ;
6171 arguments . Add ( "h|help" , "displays this message" , _ =>
6272 {
6373 arguments . WriteOptionDescriptions ( Console . Out ) ;
0 commit comments