[Webinar] Streamline your web hosting managementRegister Today

x
?
Solved

Encryption in Java and Decrypting in .NET

Posted on 2010-04-08
7
Medium Priority
?
595 Views
Last Modified: 2013-12-29
I'm encrypting with Triple DES in Java and decrypting in .NET (C#).  In .NET, the decrypted text is gibberish.  Meaning, I get some little boxes for the string value.  In the console, it just prints out question marks.  I've tried to make the process simple by not using any padding and no IV.  Can anyone see what I might be doing wrong?

Java (Eclipse Build id: 20100218-1602 and Java SE 1.6):
http://dl.dropbox.com/u/1667842/javaEncryption.zip

.NET (VS.NET 2008 C#):
http://dl.dropbox.com/u/1667842/TripleDES.zip

There isn't much code in either project.
0
Comment
Question by:brettr
  • 4
  • 2
7 Comments
 
LVL 10

Expert Comment

by:RameshS
ID: 30162827
I have put a break point at Console.WriteLine(s) and it shows the value of s is ¿¿¿¿¿¿¿¿
Since it has different characters than normal characters displayed in console, it displays then as question marks.
Actually you must set the Key property and IV property to the same values that were used for encryption in your code.   Check those details.
0
 

Author Comment

by:brettr
ID: 30163694
RameshS:

Yes - that is the same thing I see in the console.

--Actually you must set the Key property and IV property to the same values that were used for encryption in your code.   Check those details.--

Everything I'm doing is in the code.  You can see I'm using the same key to encrypt (java) and decrypt (.net).  3DES doesn't actually require an IV if both encryptor and decryptor aren't using it.

One thing I'm unsure about is the padding.  I have .NET set to Padding.None and Java to Cipher.getInstance("DESede").  Do those seem to jive?

Thanks for the help.
0
 
LVL 11

Expert Comment

by:b_levitt
ID: 30213932
My first guess is a character encoding issue.  If you're using a StreamReader to get the decrypted CryptoStream bytes, the second parameter on the constructor is the encoding type, ie..

StreamReader reader = new StreamReader(cryptoStream,Encoding.Unicode);


0
Never miss a deadline with monday.com

The revolutionary project management tool is here!   Plan visually with a single glance and make sure your projects get done.

 
LVL 11

Expert Comment

by:b_levitt
ID: 30214514
Sorry I didn't see that you had posted the code.

return Encoding.Unicode.GetString(output);

I guess I would confirm that you truely are sending unicode.  Maybe cast a single char to make sure that's not the issue?  ie byte dataToEncode = (byte)'B';

Here's here's a clip of my version of TripleDes decryption in .net:



public static String Decrypt(string base64Data, String key)
    {
      //separate the initialization vector from the encrypted data
      String[] base64Parts = base64Data.Split(':');
      byte[] iv = Convert.FromBase64String(base64Parts[1]);
      byte[] encryptedData = Convert.FromBase64String(base64Parts[0]);

      MemoryStream encryptedStream = new MemoryStream(encryptedData);
      TripleDESCryptoServiceProvider tripleDes = new TripleDESCryptoServiceProvider();
      tripleDes.IV = iv;

      //use md5 to create a 128bit key out of the preshared key for tripledes
      MD5 md5hasher = MD5.Create();
      tripleDes.Key = md5hasher.ComputeHash(
        Encoding.UTF8.GetBytes(key);


      CryptoStream cStream = new CryptoStream(
        encryptedStream,
        tripleDes.CreateDecryptor(),
        CryptoStreamMode.Read);

      StreamReader reader = new StreamReader(cStream);

      String unencryptedString = reader.ReadToEnd();

      // Close the streams.
      cStream.Close();
      encryptedStream.Close();
      reader.Close();

      // Return the unencrypted string
      return unencryptedString;

    }

Open in new window

0
 

Author Comment

by:brettr
ID: 30215835
Thanks.  So you are encrypting everything into a base64 string?  Do you convert to base64 before or after encrypting?
0
 
LVL 11

Expert Comment

by:b_levitt
ID: 30218167
after.  I don't think my code is any different than yours in that respect.  I just wanted to show you the CryptoStream way.  For all I know your way will work just as well.  But i do append the iv and the encrypted data together separated by a colon into a single 'data' param.  

Below is my corresponding encrypt function if you want to test your .net side or compare the output from your java side.
public static String Encrypt(string data, String key)
    {
      MemoryStream encryptedStream = new MemoryStream();
      TripleDESCryptoServiceProvider tripleDes = new TripleDESCryptoServiceProvider();
      tripleDes.GenerateIV();
      
      //use md5 to create a 128bit key out of the preshared key for tripledes
      MD5 md5hasher = MD5.Create();
      tripleDes.Key = md5hasher.ComputeHash(
        Encoding.UTF8.GetBytes(key));
      
      
      CryptoStream cStream = new CryptoStream(
        encryptedStream,
        tripleDes.CreateEncryptor(),
        CryptoStreamMode.Write);


      // Convert the passed string to a byte array.
      byte[] unencryptedBytes = Encoding.UTF8.GetBytes(data);

      // Write the byte array to the crypto stream and flush it.
      cStream.Write(unencryptedBytes, 0, unencryptedBytes.Length);
      cStream.FlushFinalBlock();

      //encode the encrypted data as base64 and append the initialization vector
      String base64EncryptedDataPlusIV =
        Convert.ToBase64String(encryptedStream.ToArray())
        + ":" + Convert.ToBase64String(tripleDes.IV);

      // Close the streams.
      cStream.Close();
      encryptedStream.Close();

      // Return the encrypted string plus the iv.
      return base64EncryptedDataPlusIV;

    }

Open in new window

0
 
LVL 11

Accepted Solution

by:
b_levitt earned 2000 total points
ID: 30218498
Also note I use MD5 to derive a key rather than use the bytes from the actual string secret.  The reason relates to this fact (from the .net ref for TripleDesServiceProvider):

"This algorithm supports key lengths from 128 bits to 192 bits in increments of 64 bits."

By using md5, I end up with a perfect 128bit key.  I don't know how it handles keys that don't fit those bit lengths.  That might be your problem - java might be doing one thing, and .net is doing another.

B
0

Featured Post

Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

In this post we will learn how to connect and configure Android Device (Smartphone etc.) with Android Studio. After that we will run a simple Hello World Program.
This article shows how to deploy dynamic backgrounds to computers depending on the aspect ratio of display
Video by: Michael
Viewers learn about how to reduce the potential repetitiveness of coding in main by developing methods to perform specific tasks for their program. Additionally, objects are introduced for the purpose of learning how to call methods in Java. Define …
This tutorial covers a practical example of lazy loading technique and early loading technique in a Singleton Design Pattern.
Suggested Courses
Course of the Month10 days, 5 hours left to enroll

591 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question