I am trying to generate C# MD5CryptoServiceProvider
to encode string and Java MessageDigest.getInstance("MD5")
to encode string, but both outputs are different. There are so many sample are already available on stackoverlflow
but still stuck on some where.
Following is my C# code:
MD5CryptoServiceProvider md5Hasher = new MD5CryptoServiceProvider();
Byte[] hashedDataBytes = null;
UTF8Encoding encoder = new UTF8Encoding();
hashedDataBytes = md5Hasher.ComputeHash(encoder.GetBytes("NSI#1234@"));
string strPassword = string.Empty;
foreach (byte b in hashedDataBytes)
{
strPassword = strPassword + b.ToString();
}
return strPassword;
The C#
code is freeze code, i have not permission to change this code.
Following is my Java code:
MessageDigest messageDigest = MessageDigest.getInstance("MD5");
byte[] digest = messageDigest.digest("NSI#1234@".getBytes("UTF-8"));
String hash = new BigInteger(1, digest).toString();
System.out.println(hash);
C# code output: 158163028351382321031971922721528189209213
Java Code output: 210864369951346339831795420458152481237
C# generate 42 number and java generate 39 number. if i change the value of new BigInteger(1, digest).toString(8)
it generates 43 number and if i change new BigInteger(1, digest).toString(9)
it generates 41 number.
Neither your C# code nor your Java code are good ways to convert a hash to a string. I strongly suspect you've got the same bytes in both cases, but you're converting them to strings differently.
Your C# code is just converting each byte to its decimal representation. (It's also doing so with repeated string concatenation. Ick.) Your Java code will ignore leading 0s and is currently using decimal. You can call toString(16)
to produce hex, but it will still ignore leading zeroes.
If you definitely want hex, you can use BitConverter.ToString(byte[])
to get a hex representation in .NET, although you may want to remove the -
it will place between each byte; in Java there are various libraries available such as Apache Commons Codec (Hex
) or Guava (BaseEncoding.base16()
). Or use some code from one of the many answers to hex encoding in Java on Stack Overflow, such as this one.
Alternatively, you could use Base64 - again, there are multiple options available, such as BitConverter.ToBase64String
in .NET and the iharder public domain library for Java.
If your C# code is truly frozen (run to the hills!) then the equivalent (well, slightly cleaner) Java code would be something like:
StringBuilder builder = new StringBuilder();
for (byte b : digest) {
builder.append(b & 0xff); // Convert signed to unsigned
}
I'd also urge you to use StandardCharsets.UTF_8
if you're using Java 7+.
But I would strongly advise fixing the C# code if you possibly can. Even if you're in "code freeze" that presumably doesn't prohibit you from fixing important bugs - and if you're storing these values, it'll be a lot easier to fix this now than it will to do so later.
See more on this question at Stackoverflow