5

I am trying to decrypt something, which was encrypted using RijndaelManaged of .NET/C#, using Java to decrypt.

The C# program is not mine; I cannot change it to be more interoperable. But I know how it is encrypting:

byte[] bytes = new UnicodeEncoding().GetBytes(password); // edit: built-in is 8chars FileStream fileStream = new FileStream(outputFile, FileMode.Create); RijndaelManaged rijndaelManaged = new RijndaelManaged(); CryptoStream cryptoStream = new CryptoStream((Stream) fileStream, rijndaelManaged.CreateEncryptor(bytes, bytes), CryptoStreamMode.Write); 

I do not know how to decrypt this on the Java end. The closest thing to useful I have found is this blog post, but it is light on actual details and I could not implement a decrypter.

Edit: I'm an idiot and now have it working.

UnicodeEncoding is UTF-16LE, while I was using UTF-8. Switching to the proper encoding when plugging the password in has fixed the program.

I also needed to get BouncyCastle and do Cipher.getInstance("AES/CBC/PKCS7Padding", "BC");

finaledit: Here's the code to decrypt a default RijndaelManaged stream from .NET in Java, assuming it was created using a raw password as the key:

Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider()); String password = "kallisti"; // only 8, 12, or 16 chars will work as a key byte[] key = password.getBytes(Charset.forName("UTF-16LE")); Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding", "BC"); cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(key, "AES"), new IvParameterSpec(key)); return cipher; // then use CipherInputStream(InputStream, Cipher) 

And remember: if you control the C# end, don't use an underived password as your key!

3
  • 1
    unsolicited advice: Don't use new UnicodeEncoding().GetBytes(password); to get the bytes for a password. For why, see en.wikipedia.org/wiki/PBKDF2 and tools.ietf.org/html/rfc2898 especially section 3. Fortunately, both .NET and Java have RFC2898-compliant (aka PKCS5, aka PBKDF2) key derivation classes. Your apps should use them. Commented May 22, 2011 at 18:31
  • 1
    See also, stackoverflow.com/questions/2375541/… for a question on PKBDF2 in Java. Commented May 22, 2011 at 18:36
  • @Cheeso: The C# app isn't mine; I know using a raw password as a key is a terrible idea. It's also not encrypting anything that actually needs crypto, just a binary blob the app writer didn't want other apps to be able to read. Commented May 24, 2011 at 3:38

1 Answer 1

3

It's possible using the standard AES decryption. Rijndel is just a superset of AES which is more lax with particular options. See Rijndael support in Java for more details.

From the answer given in the linked question:

byte[] sessionKey = null; //Where you get this from is beyond the scope of this post byte[] iv = null ; //Ditto byte[] plaintext = null; //Whatever you want to encrypt/decrypt Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); //You can use ENCRYPT_MODE or DECRYPT_MODE cipher.calling init(Cipher.DECRYPT_MODE, new SecretKeySpec(sessionKey, "AES"), new IvParameterSpec(iv)); byte[] ciphertext = cipher.doFinal(plaintext); 
Sign up to request clarification or add additional context in comments.

7 Comments

You have that bit slightly backwards - AES is a subset of Rijndael, particularly on the block size. AES will strictly use a block size of 128 (Reference FIPS 197), whereas Rijndael will give you some flexibility.
Thanks for the advice :) Edited answer. Just got it a bit confused.
"java.security.InvalidKeyException: Invalid AES key length: 8 bytes" "java.security.InvalidAlgorithmParameterException: Wrong IV length: must be 16 bytes long" I have tried this code, but it does not work. I am using an identical password to what the C# end is doing. The C# end is using a raw plaintext password to plug into the cipher; the above code seems to expect to receive a byte array derived from a password.
See if this works any better: cs.ucdavis.edu/~rogaway/ocb/ocb-java/Rijndael.java. It looks like the AES support needs particular key lengths (128, 192, 256, etc.). So you'd have to craft the key on either end to be compatible with AES.
I know I have to craft the key to be compatible with AES. But I need to do that in a way that is equivalent to what the C# program is doing. The C# program is simply providing RijndaeManaged with an 8-byte password, which is then apparently automatically derived into a proper key. I don't know how to do this in Java.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.