Converting C# cryptography to Java -


i have been tasked converting c# cryptography method java , stuck. know c# codes works, having trouble getting java code work.

here c# code:

private const int nb = 4; // legal values:  4 = 128-bit blocks  public static void decrypt(byte[] input, stream output)     {          var s1 = new memorystream(input);         const int buffersize = 1024;         byte[] buffer = new byte[buffersize];          input.read(buffer, 0, 4);         int pad = buffer[3];          rijndaelmanaged rijndael = new rijndaelmanaged();         rijndael.blocksize = nb * 32;         rijndael.keysize = buffer[1] * 32;          rijndael.mode = ciphermode.ecb;         rijndael.padding = paddingmode.none;          byte[] key = getkey(buffer[1]);         icryptotransform decryptor = rijndael.createdecryptor(key, getiv());          int bytes;         while ((bytes = input.read(buffer, 0, buffersize)) > 0)         {             (int = 0; < bytes; += rijndael.blocksize)             {                 decryptor.transformblock(buffer, i, rijndael.blocksize, buffer, i);             }             output.write(buffer, 0, bytes);         }         output.setlength(output.length - pad - 4);     } 

and here attempt in java far:

public static string decrypt(byte[] input) throws exception {     cipher cipher = cipher.getinstance("aes/ecb/nopadding");     byte[] key = getkey(input[1]);     secretkey secretkey = new secretkeyspec(key, 0, key.length, "aes/ecb/nopadding");     cipher.init(cipher.decrypt_mode, secretkey, new ivparameterspec(getiv()));     // remove first 4 since c# code reads past     byte[] finaldecoded = arrays.copyofrange(input, 4, input.length);     byte[] decryptedval = cipher.dofinal(finaldecoded);     return new string(decryptedval); } 

some more information

  • for getiv , getkey, can guarantee results in java same (i have compared every byte), not including methods because believe sensitive information. can guarantee input byte[] identical , (redundantly) same length.

  • debugging attempts: current error in java ecb mode cannot use iv.

    • when remove code : new ivparameterspec(getiv()) error: wrong algorithm: aes or rijndael required
    • if change algorithm aes or rijndael error: input length must multiple of 16 when decrypting padded cipher. input length starting 424 , 420 after reading past/removing first 4 bytes. have verified input bytes same java , c#.

where going wrong in java code?

you getting error ecb mode cannot use iv because ecb doesn't perform chaining, iv meaningless. difference java throws error whereas c# ignores iv.

when remove code : new ivparameterspec(getiv()) error: wrong algorithm:aes or rijndaelrequired

if change algorithm aes or rijndael error: input length must multiple of 16 when decrypting withpadded cipher.

you had right idea, went far. error secretkeyspec, doesn't care mode, algorithm. cipher specify mode. also, rijndael , aes aren't quite same thing.

so start changing first few lines this:

cipher cipher = cipher.getinstance("rijndael/ecb/nopadding"); byte[] key = getkey(input[1]); secretkey secretkey = new secretkeyspec(key, 0, key.length, "rijndael"); cipher.init(cipher.decrypt_mode, secretkey); 

note since you're using entire key don't need offset , length arguments, can do

secretkey secretkey = new secretkeyspec(key, "rijndael"); 

the original c# code has not-so-obvious behavior:

while ((bytes = input.read(buffer, 0, buffersize)) > 0) {     (int = 0; < bytes; += rijndael.blocksize)     {         decryptor.transformblock(buffer, i, rijndael.blocksize, buffer, i);     }     output.write(buffer, 0, bytes); } 

when loop gets end of input, copy left of buffer. unless last read 1024 bytes, there residue previous loop (or initialization if gets whole input 1 read operation) after end of input.

the inner loop decrypts 1 16-byte block @ time. in case of 420-byte example, last block consist of remaining 4 bytes of input and 12 more bytes of garbage. it's okay because output.write writes bytes number of bytes truncate garbage. have replicate behavior in java code.


side note: absolutely have use ecb? it's not secure...


Comments