By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
435,561 Members | 3,265 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 435,561 IT Pros & Developers. It's quick & easy.

C#-app: Can't decrypt my AES-128 C#-encrypted byte array in java

P: 42
I'm trying to decrypt a byte array in java that was encrypted in C#. I don't get any error messages, just a result that's completely not what I was hoping for.

I think I am using the same type of algorithm, initialization vector (IV), mode, padding, key etc, but I just don't get the two languages to "understand each other", or, in other words, I must be missing out on something crucial.

I encrypt a byte array in C# and send over the byte initialization vector used for encrypting it as well as the encrypted byte to java. In java I use the received initialization vector to try to decrypt the received encrypted byte array. And I don't get anything near the original plaintext.

I leave out the communication code between the two applications since I don't think that's where the problem is. Though I'm not sure, of course, but let's try this first. (Why I don't think that's the problem? I print out the arrays in my C# code as well as in my java code, once they're received in the java code, and they look exactly the same.)

Here's the encryption code I use so you get the idea of the encryption methods I'm using. I'm trying to achieve AES-128, CBC, no padding in both applications.

NOTE: Of course, in my application I use the IV received from C#, not "tmpiv" as in this example. Also, I use the received encrypted plaintext-buffer from C#... yeah, you get the point. I just wanted to post runnable code..

Any ideas or hints to lead me in the right direction would be extremely appreciated! Cheers!

Expand|Select|Wrap|Line Numbers
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. using System.Security.Cryptography;
  5. using System.IO;
  6.  
  7. namespace forumapp
  8. {
  9.     class Program
  10.     {
  11.         static RijndaelManaged rijndaelCipher;
  12.  
  13.         static void Main(string[] args)
  14.         {
  15.           byte[] plaintext = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF };
  16.           Console.WriteLine ("\nPlaintext is: ");
  17.           DisplayBytes(plaintext);
  18.  
  19.           initCrypt();
  20.  
  21.           byte[] ciphered = Encrypt(plaintext);
  22.           Console.WriteLine("\nEncrypted plaintext is: ");
  23.           DisplayBytes(ciphered);
  24.  
  25.           byte[] deciphered = Decrypt(ciphered);
  26.           Console.WriteLine("\nDecrypting encrypted plaintext, we get plaintext back: ");
  27.           DisplayBytes(deciphered);
  28.  
  29.           Console.WriteLine("\nDone");
  30.           Console.ReadLine();
  31.  
  32.         }
  33.  
  34.         public static void initCrypt()
  35.         {
  36.             byte[] keyBytes = System.Text.UTF8Encoding.UTF8.GetBytes ("abcdefghijklmnop");
  37.  
  38.             rijndaelCipher = new RijndaelManaged();
  39.             PasswordDeriveBytes pdb = new PasswordDeriveBytes(keyBytes, new SHA1CryptoServiceProvider().ComputeHash(keyBytes));
  40.             byte[] key = pdb.GetBytes(32);
  41.             byte[] iv = pdb.GetBytes(16);
  42.             rijndaelCipher.Mode = CipherMode.CBC;
  43.             rijndaelCipher.Padding = PaddingMode.None;
  44.             rijndaelCipher.KeySize = 128;
  45.             rijndaelCipher.BlockSize = 128;
  46.             rijndaelCipher.Key = key;
  47.             rijndaelCipher.IV = iv;
  48.         }
  49.  
  50.         public static byte[] Encrypt(byte[] plainBytes)
  51.         {
  52.             ICryptoTransform transform = rijndaelCipher.CreateEncryptor();
  53.             using (MemoryStream ms = new MemoryStream(plainBytes))
  54.             {
  55.                 using (CryptoStream cs = new CryptoStream(ms, transform, CryptoStreamMode.Read))
  56.                 {
  57.                     return ReadFully(cs);
  58.                 }
  59.             }
  60.         }
  61.  
  62.         public static byte[] Decrypt(byte[] encryptedData)
  63.         {
  64.             ICryptoTransform transform = rijndaelCipher.CreateDecryptor();
  65.             using (MemoryStream ms = new MemoryStream(encryptedData))
  66.             {
  67.                 using (CryptoStream cs = new CryptoStream(ms, transform, CryptoStreamMode.Read))
  68.                 {
  69.                     return ReadFully(cs);
  70.                 }
  71.             }
  72.         }
  73.  
  74.         public static byte[] ReadFully(Stream stream)
  75.         {
  76.             byte[] buffer = new byte[32768];
  77.             using (MemoryStream ms = new MemoryStream())
  78.             {
  79.                 while (true)
  80.                 {
  81.                     int read = stream.Read(buffer, 0, buffer.Length);
  82.                     if (read <= 0)
  83.                         return ms.ToArray();
  84.                     ms.Write(buffer, 0, read);
  85.                 }
  86.             }
  87.         }
  88.  
  89.         static void DisplayBytes(byte[] bytes)
  90.         {
  91.             for (int i = 0; i < bytes.Length; ++i)
  92.             {
  93.                 Console.Write(bytes[i].ToString("x2") + " ");
  94.                 if (i > 0 && i % 16 == 0) Console.Write("\n");
  95.             }
  96.             Console.WriteLine("");
  97.         }
  98.  
  99.     }
  100. }
Expand|Select|Wrap|Line Numbers
  1. import java.io.*;
  2. import javax.crypto.Cipher;
  3. import javax.crypto.NoSuchPaddingException;
  4. import javax.crypto.spec.IvParameterSpec;
  5. import javax.crypto.spec.SecretKeySpec;
  6.  
  7.  
  8. public class Main {
  9.  
  10.     public Main() {
  11.     }
  12.  
  13.     public static void main(String[] args) {
  14.         byte[] keyBytes = ("abcdefghijklmnop").getBytes();
  15.          byte[] plaintext = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
  16.                               (byte)0x88, (byte)0x99, (byte)0xaa, (byte)0xbb,
  17.                               (byte)0xcc, (byte)0xdd, (byte)0xee, (byte)0xff };
  18.  
  19.          byte[] tmpIV = {0x43, (byte)0x6d, 0x22, (byte)0x9a, 0x22,
  20.                         (byte)0xf8, (byte)0xcf, (byte)0xfe, 0x15, 0x21,
  21.                         (byte)0x0b, 0x38, 0x01, (byte)0xa7, (byte)0xfc, 0x0e};
  22.  
  23.          System.out.println("Plaintext is:");
  24.          displayBytes(plaintext);
  25.  
  26.          byte[] encrypted = encrypt(plaintext,keyBytes,tmpIV);
  27.          System.out.println("Encrypted plaintext is:");
  28.          displayBytes(encrypted);
  29.  
  30.          byte[] decrypted = decrypt(encrypted,keyBytes,tmpIV);
  31.          System.out.println("Decrypting encrypted plaintext, we get plaintext back:");
  32.          displayBytes(decrypted);
  33.  
  34.  
  35.     }
  36.  
  37.      public static byte[] decrypt(byte[] cipherText, byte[] key, byte [] iv)
  38.     {
  39.       try{    
  40.       Cipher c = Cipher.getInstance("AES/CBC/NoPadding");
  41.       SecretKeySpec sks = new SecretKeySpec(key, "AES");
  42.       IvParameterSpec ips = new IvParameterSpec(iv);
  43.       c.init(Cipher.DECRYPT_MODE, sks, ips);   
  44.       //Re-use of "cipherText"
  45.       cipherText = c.doFinal(cipherText);
  46.       }
  47.       catch(Exception e){ System.out.println("Exception caught:"+e.getMessage());}
  48.       return cipherText;
  49.    }
  50.  
  51.      public static byte[] encrypt(byte[] plainText, byte[] key, byte [] iv)
  52.     {
  53.      try{    
  54.       Cipher c = Cipher.getInstance("AES/CBC/NoPadding");
  55.       SecretKeySpec sks = new SecretKeySpec(key, "AES");
  56.       IvParameterSpec ips = new IvParameterSpec(iv);
  57.       c.init(Cipher.ENCRYPT_MODE, sks, ips);
  58.       //Re-use of "plainText"
  59.       plainText = c.doFinal(plainText);
  60.       }
  61.       catch(Exception e){System.out.println("Exception caught:"+e.getMessage());}
  62.       return plainText;      
  63.    }
  64.  
  65.  
  66.      public static void displayBytes(byte[] bytes) {
  67.         StringBuffer ret = new StringBuffer(bytes.length);
  68.         for (int i = 0; i < bytes.length; i++) {
  69.             String hex = Integer.toHexString(0x0100 + (bytes[i] & 0x00FF)).substring(1);
  70.             ret.append((hex.length() < 2 ? "0" : " ") + hex);
  71.         }
  72.         System.out.println (ret.toString());
  73.     }
  74. }
Aug 29 '07 #1
Share this Question
Share on Google+
1 Reply


P: 42
My mistake. (Sorry for being such a 'moron'...)
The key is not the same!!
Of course I shouldn't use rijndaelCipher.Key = key, where key = pdb.GetBytes(32)
(PasswordDeriveBytes).
It should be "rijndaelCipher.Key = keyBytes.
Then it works like a charm!
"I'm so happy, oh so happy..." cheers
Aug 30 '07 #2

Post your reply

Sign in to post your reply or Sign up for a free account.