Reputation: 31
I have a authentication process written in Java which encrypts a string into MD5 and generates a string and takes only the first 8 digits of that string. In this example that generated string is "89a5c474".
Afterwards I have this following piece of Java Code in which I use a TripleDesEncryption.
public static byte[] encrypt(byte[] keybyte, byte[] src) throws NoSuchAlgorithmException, NoSuchPaddingException, Exception
{
System.out.println("Key Byte " + byte2hex(keybyte) + "Key Byte Array" + keybyte);
System.out.println("Key String " + byte2hex(src));
SecretKey deskey = new SecretKeySpec(keybyte, DESede);
Cipher c1 = Cipher.getInstance(Algorithm);
c1.init(Cipher.ENCRYPT_MODE, deskey);
return c1.doFinal(src);
}
public static void main(String[] args)
{
final byte[] rawKey = "89a5c474".getBytes();
final byte[] keyBytes = new byte[24];
for (int i = 0; i <rawKey.length; i++)
{
keyBytes[i] = rawKey[i];
}
for (int i = rawKey.length; i <keyBytes.length; i++)
{
keyBytes[i] = (byte)0;
}
String szSrc = "20126303$4A6D9BD0DDD094B76C111577A49EB87A$Guest$PC$193.92.123.5$$Reserved$CTC";
byte[] encoded = null;
try
{
encoded = encrypt(keyBytes, szSrc.getBytes());
}
catch (Exception e)
{
e.printStackTrace();
}
}
which results into the string representation of the encrypted bytes and I am able to successfully authenticate with the platform. However since I have to deploy my code into a console application in C#, I have tried to replicate the above code to no avail, and returns me the error "Specified key is a known weak key for 'TripleDES' and cannot be used."
public static string AuthenticatePassword(string token, string hashPassword)
{
byte[] rawKey = UTF8Encoding.UTF8.GetBytes(hashPassword);
byte[] keyBytes = new byte[24];
for (var i = 0; i < rawKey.Length; ++i)
{
keyBytes[i] = rawKey[i];
}
for (int i = rawKey.Length; i < keyBytes.Length; i++)
{
keyBytes[i] = 0;
}
string keyString = "20126303$" + token + "$Guest$PC$193.92.123.5$$Reserved$CTC";
return Encrypt(keyBytes, System.Text.Encoding.ASCII.GetBytes(keyString), rawKey, keyString);
}
public static string Encrypt(byte[] keyBytes, byte[] keyString)
{
try
{
TripleDESCryptoServiceProvider des = new TripleDESCryptoServiceProvider();
des.Key = keyBytes;
des.Mode = CipherMode.ECB;
des.Padding = PaddingMode.PKCS7;
ICryptoTransform ic = des.CreateEncryptor();
byte[] enc = ic.TransformFinalBlock(keyString, 0, keyString.Length);
}
catch (Exception e)
{
Console.WriteLine("[Encryption Error] {0}", e.Message);
}
return string.Join(string.Empty, enc.Select(x => x.ToString("X2")));
}
I have searched several sources and I have stumbled upon this workaround where the application successfully manages to generate me a key, but unfortunately it is not equal with the code that Java yields.
TripleDESCryptoServiceProvider sm = new TripleDESCryptoServiceProvider();
MethodInfo mi = sm.GetType().GetMethod("_NewEncryptor", BindingFlags.NonPublic | BindingFlags.Instance);
object[] Par = { EmptyKey, CipherMode.ECB, keyBytes, sm.FeedbackSize, 0 };
ICryptoTransform trans = mi.Invoke(sm, Par) as ICryptoTransform;
byte[] enc = trans.TransformFinalBlock(keyString, 0, keyString.Length);
Java = d68d8423eb01421e8f23c118d3aef6a6998d8f2a62ceb697377195aa979fe5e97141454716e6d6b41c56d0af296bc4d6ab2979c7d9233898baef5c9f38fa9fd286d8a6c2a2a4b6697d1eb7c
C# = FF9772125DC1E3A4C9B63DFD429FB3CDA43732331025F9B73A092A942121F6869C372AE40B0DB1991DB0FD04CE5924EB213B8F303721C79F8F4CCA384711B7E2ADCC862E0003E18EF3CC0DA2CD4B7488
Upvotes: 2
Views: 1092
Reputation: 31
I've managed to bypass and recreate the 3DES Encryption on C# with the functions and constructors that are used in Java. For all those who are encountering this problem, you can use Bouncy Castle's assembly and follow these links for more info: http://www.bouncycastle.org/csharp/ and http://www.go4expert.com/articles/bouncy-castle-net-implementation-triple-t24829/
Upvotes: 1