I have a java program (third party so can't edit) that is generating a Base64 encoded string from a MD5 hash. It's not being used for security reasons in this instance, more to get a unique value for the string provided for easy comparison later on.
I'm trying to generate the same Base64 string in my C# application so I can also use it for comparison later.
Here's the code and then I'll go into what I've tried.
Relevant parts of the Java program (pulled from the IntelliJ decompiler):
String encodedValue =
encode("Lot#: 9999 ExpDate: Mar 6, 2020 Date: Apr 1, 2020 QtyD: 0.56 Chk: True Int: 120 Mon: $90.00");
public static String encode(String password) throws IOException, NoSuchAlgorithmException, MessagingException {
ByteArrayOutputStream out = new ByteArrayOutputStream();
try {
OutputStream encoder = MimeUtility.encode(out, "base64");
try {
byte[] encrypted = encrypt(password);
encoder.write(encrypted);
encoder.flush();
return new String(out.toByteArray());
catch(...) {}
catch(...){}
}
private static byte[] encrypt(String password) throws NoSuchAlgorithmException {
MessageDigest algorithm = MessageDigest.getInstance("MD5");
algorithm.reset();
algorithm.update(password.getBytes());
return algorithm.digest();
}
C# section
string input =
"Lot#: 9999 ExpDate: Mar 6, 2020 Date: Apr 1, 2020 QtyD: 0.56 Chk: True Int: 120 Mon: $90.00";
using (System.Security.Cryptography.MD5 md5 = System.Security.Cryptography.MD5.Create())
{
byte[] inputBytes = Encoding.GetEncoding(28591).GetBytes(input); //matches Java so far
byte[] hashBytes = md5.ComputeHash(inputBytes);
string base64 = Convert.ToBase64String(hashBytes);
}
If I run both input byte[] (password.getBytes() and Encoding.GetEncoding(28591).GetBytes(input)) through the Base 64 encoder, they both return the same value.
TG90IzogOTk5OSAgRXhwRGF0ZTogTWFyIDYsIDIwMjAgIERhdGU6IEFwciAxLCAyMDIwICBRdHlEOiAwLjU2ICBDaGs6IFRydWUgIEludDogMTIwICBNb246ICQ5MC4wMA==
This leads me to believe the encoding is correct between both of them.
If I inspect the encrypted byte[], the values don't match
Based on this and this I realized that Java uses signed numbers so the display output on the debugger really isn't going to match, but the actual values still should.
I tried using
for (byte b : bytes) {
System.out.println(b & 0xFF);
}
to view the signed counterpart in c#, C# signed array but the arrays don't match still.
And for the final output, the base64 encoded strings
Java
0mfvZiQ7tDOnMsP/qH8CLQ==
C#
W2afrKbW3jHPMv7HHnc8nw==
I'm not sure if the MessageDigest is doing something additional in the encryption that I can't see to replicate, or if I'm missing something entirely.
I'm able to debug both sides so if any additional information would be helpful, let me know.
Any help would be greatly appreciated!