TripleDES algorithm: from .NET to Java
-
15-06-2021 - |
Question
I have this vb.net code ( but I think meaning code is equivalent for c# too) that I have to replicate in Java and I can't modify it in anyway (just replicate):
Public Shared Function Encrypt(ByVal plainText As String, Optional key As String = "") As String
If String.IsNullOrEmpty(key) Then key = "sfdjf48mdfdf3054"
Dim encrypted As String = Nothing
Try
Dim inputBytes As Byte() = ASCIIEncoding.ASCII.GetBytes(plainText)
Dim pwdhash As Byte() = Nothing
'generate an MD5 hash from the password.
'a hash is a one way encryption meaning once you generate
'the hash, you cant derive the password back from it.
Dim hashmd5 As New MD5CryptoServiceProvider()
pwdhash = hashmd5.ComputeHash(ASCIIEncoding.ASCII.GetBytes(key))
hashmd5 = Nothing
' Create a new TripleDES service provider
Dim tdesProvider As New TripleDESCryptoServiceProvider()
tdesProvider.Key = pwdhash
tdesProvider.Mode = CipherMode.ECB
encrypted = Convert.ToBase64String(tdesProvider.CreateEncryptor().TransformFinalBlock(inputBytes, 0, inputBytes.Length))
Catch e As Exception
Dim str As String = e.Message
Throw
End Try
Return encrypted
End Function
Exactly, this is a .NET Utility Class function.
Now,
I don't know how to replicate
TripleDESCryptoServiceProvider()
In java code I began to write some code, but I don't know how to continue:
public static String encrypt(String plaintext, String enctoken){
if(enctoken == null)
enctoken = "sfdjf48mdfdf3054";
String encrypted = null;
byte[] plaintextByte = EncodingUtils.getAsciiBytes(plaintext);
//nel caso non funzionasse provare getBytes semplicemente
byte[] pwd = EncodingUtils.getAsciiBytes(Connessione.md5(enctoken));
try {
Cipher cipher = Cipher.getInstance("DESEDE/ECB/NoPadding");
SecretKeySpec myKey = new SecretKeySpec(pwd,"DESede");
cipher.init( Cipher.ENCRYPT_MODE, myKey);
try {
byte[] encryptedPlainText= cipher.doFinal(plaintextByte);
encrypted = Base64.encodeToString(encryptedPlainText, 0);
return encrypted;
} catch (IllegalBlockSizeException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (BadPaddingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchPaddingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvalidKeyException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return "";
}
UPDATE:
I've just updated code. Now should be good. Enctoken String will be a string data rappresentation (just known). In this way, only if second parameter is NULL then fixed key is setted
UPDATE 2
Unfortunally c# hash is always different from Java hash!! How to replicate this in java ??
Dim hashmd5 As New MD5CryptoServiceProvider()
pwdhash = hashmd5.ComputeHash(ASCIIEncoding.ASCII.GetBytes(key))
hashmd5 = Nothing
' Create a new TripleDES service provider
Dim tdesProvider As New TripleDESCryptoServiceProvider()
tdesProvider.Key = pwdhash
tdesProvider.Mode = CipherMode.ECB
encrypted = Convert.ToBase64String(tdesProvider.CreateEncryptor().TransformFinalBlock(inputBytes, 0, inputBytes.Length))
I tried in this way but it doesn't work:
HASH
public static final String md5(byte[] s) {
try {
MessageDigest m = MessageDigest.getInstance("MD5");
byte[] digest = m.digest(s);
String hash = EncodingUtils.getAsciiString(digest, 0, 16);
Log.i("MD5", "Hash: "+hash);
return hash;
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return "";
}
Solution
Fixed by myself! Following function gives same MD5 HASH result:
JAVA HASH MD5
public static final byte[] md5(String s) {
try {
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] messageDigest = md.digest(s.getBytes("UTF-8"));
String md5 = EncodingUtils.getString(messageDigest, "UTF-8");
Log.i("Function MD5", md5);
Log.i("Function MD5 Length","Length: "+ md5.length());
return messageDigest;
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
VB.NET HASH MD5
Dim hashmd5 As New MD5CryptoServiceProvider()
pwdhash = hashmd5.ComputeHash(ASCIIEncoding.ASCII.GetBytes(key))
And, TRIPLE-DES ECB JAVA is
try {
Cipher cipher = Cipher.getInstance("DESEDE/ECB/PKCS5Padding");
SecretKeySpec myKey = new SecretKeySpec(hash,"DESede");
cipher.init(Cipher.ENCRYPT_MODE, myKey);
try {
byte[] encryptedPlainText = cipher.doFinal(plaintextByte);
encrypted = Base64.encodeToString(encryptedPlainText, 0);
Log.i("ENCRYPT", "Pwd encrypted: "+encrypted);
return encrypted;
} catch (IllegalBlockSizeException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (BadPaddingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchPaddingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvalidKeyException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
TRIPLE-DES VB.NET is
' Create a new TripleDES service provider
Dim tdesProvider As New TripleDESCryptoServiceProvider()
tdesProvider.Key = pwdhash
tdesProvider.Mode = CipherMode.ECB
encrypted = Convert.ToBase64String(tdesProvider.CreateEncryptor().TransformFinalBlock(inputBytes, 0, inputBytes.Length))
OTHER TIPS
There is no such thing as an IV for ECB mode (which is one of the things that is unsafe in your application, you should at least use CBC mode).
As for the key, you just calculated one, why are you stuck here? What exception do you get? And again, using ASCII characters instead of full bytes is unsafe; it makes you vulnerable to (at least) brute force attacks.