As far as I can tell from reading the Java code here and here, the difference is that it performs multiple iterations of the MD5 algorithm.
Taking this answer and modifying it, I've reached this:
public static string CreateMD5(string input, string salt = null, int iterations = 1)
{
// Use input string to calculate MD5 hash
using (System.Security.Cryptography.MD5 md5 = System.Security.Cryptography.MD5.Create())
{
byte[] inputBytes = System.Text.Encoding.ASCII.GetBytes(input);
// modification from linked answer: prefix with salt
if (!string.IsNullOrEmpty(salt) != null)
{
inputBytes = System.Text.Encoding.ASCII.GetBytes(salt).Concat(inputBytes).ToArray();
}
byte[] hashBytes = md5.ComputeHash(inputBytes);
// modification from linked answer: iterate N times
for (int i = 1; i < iterations; ++i)
{
hashBytes = md5.ComputeHash(hashBytes);
}
// Convert the byte array to hexadecimal string
StringBuilder sb = new StringBuilder();
for (int i = 0; i < hashBytes.Length; i++)
{
sb.Append(hashBytes[i].ToString("X2"));
}
return sb.ToString();
}
}
public static string enPwd(string username, string pwd)
{
return CreateMD5(username + pwd, username, 2);
}
As you can see, you just need to hash the resulting hash.
I've replicated what I saw in the Java library here, and the C# code produces the same result here.