One problem that I have had to solve in the past was making encryption between Java and .NET possible. Specifically, I was charged to read an encrypted query string parameter from a Java system in my ASP.NET application. After a few iterations of incompatible implementations, I created an implementation in both .NET (c#) and Java to ensure compatibility.
Since this caused me so much pain, I thought I would share my implementation with you in hopes that it will work for you as well.
Let me know if you have any questions or want to provide a decrypt implementation for the java class.
DOWNLOAD C# CLASS FILE
DOWNLOAD JAVA CLASS FILE
.NET (C#) Implementation
/// <summary>
/// Encryption utility class that implements Triple DES algorithm
/// </summary>
public class TripleDESImplementation
{
//Encryption Key
private byte[] EncryptionKey { get; set; }
// The Initialization Vector for the DES encryption routine
private byte[] IV { get; set; }
/// <summary>
/// Constructor for TripleDESImplementation class
/// </summary>
/// <param name="encryptionKey">The 24-byte encryption key (24 character ASCII)</param>
/// <param name="IV">The 8-byte DES encryption initialization vector (8 characters ASCII)</param>
public TripleDESImplementation(string encryptionKey, string IV)
{
if (string.IsNullOrEmpty(encryptionKey))
{
throw new ArgumentNullException("'encryptionKey' parameter cannot be null.", "encryptionKey");
}
if (string.IsNullOrEmpty(IV))
{
throw new ArgumentException("'IV' parameter cannot be null or empty.", "IV");
}
EncryptionKey = Encoding.ASCII.GetBytes(encryptionKey);
// Ensures length of 24 for encryption key
Trace.Assert(EncryptionKey.Length == 24, "Encryption key must be exactly 24 characters of ASCII text (24 bytes)");
this.IV = Encoding.ASCII.GetBytes(IV);
// Ensures length of 8 for init. vector
Trace.Assert(IV.Length == 8, "Init. vector must be exactly 8 characters of ASCII text (8 bytes)");
}
/// <summary>
/// Encrypts a text block
/// </summary>
public string Encrypt(string textToEncrypt)
{
TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider();
tdes.Key = EncryptionKey;
tdes.IV = IV;
byte[] buffer = Encoding.ASCII.GetBytes(textToEncrypt);
return Convert.ToBase64String(tdes.CreateEncryptor().TransformFinalBlock(buffer, 0, buffer.Length));
}
/// <summary>
/// Decrypts an encrypted text block
/// </summary>
public string Decrypt(string textToDecrypt)
{
byte[] buffer = Convert.FromBase64String(textToDecrypt);
TripleDESCryptoServiceProvider des = new TripleDESCryptoServiceProvider();
des.Key = EncryptionKey;
des.IV = IV;
return Encoding.ASCII.GetString(des.CreateDecryptor().TransformFinalBlock(buffer, 0, buffer.Length));
}
}
Java Implementation
public class TripleDesImplementation {
private String key;
private String initializationVector;
public TripleDesImplementation(String key, String initializationVector)
{
this.key = key;
this.initializationVector = initializationVector;
}
public String encryptText(String plainText) throws Exception{
//---- Use specified 3DES key and IV from other source --------------
byte[] plaintext = plainText.getBytes();
byte[] tdesKeyData = key.getBytes();
byte[] myIV = initializationVector.getBytes();
Cipher c3des = Cipher.getInstance("DESede/CBC/PKCS5Padding");
SecretKeySpec myKey = new SecretKeySpec(tdesKeyData, "DESede");
IvParameterSpec ivspec = new IvParameterSpec(myIV);
c3des.init(Cipher.ENCRYPT_MODE, myKey, ivspec);
byte[] cipherText = c3des.doFinal(plaintext);
return Base64Coder.encodeString(new String(cipherText));
}
}