0

I have a C# project to verify a file's MD5. I use System.Security.Cryptography.MD5 to calculate the MD5 in C#.

But it is different from the MD5 in Java.

EDIT: I have found the c# code is correct one. Thanks to Andy. May I know how to correct the Java code?

C# code:

public static String ComputeMD5(String fileName)
{
    String hashMD5 = String.Empty;
    
    if (System.IO.File.Exists(fileName))
    {
        using (System.IO.FileStream fs = new System.IO.FileStream(fileName, System.IO.FileMode.Open, System.IO.FileAccess.Read))
        {    
            System.Security.Cryptography.MD5 calculator = System.Security.Cryptography.MD5.Create();

            Byte[] buffer = calculator.ComputeHash(fs);

            calculator.Clear();
            
            StringBuilder stringBuilder = new StringBuilder();
            for (int i = 0; i < buffer.Length; i++){
                stringBuilder.Append(buffer[i].ToString("x2"));
            }
            hashMD5 = stringBuilder.ToString();  
        }
    }
    return hashMD5;
}    

Java Code:

public static String ComputeMD5(File file) {
    if (!file.isFile()) {
        return null;
    }
    MessageDigest digest = null;
    FileInputStream in = null;
    byte buffer[] = new byte[1024];
    int len;
    try {
        digest = MessageDigest.getInstance("MD5");
        in = new FileInputStream(file);
        while ((len = in.read(buffer, 0, 1024)) != -1) {
            digest.update(buffer, 0, len);
        }
        in.close();
    } catch (Exception e) {
        e.printStackTrace();
        return null;
    }
    return bytesToHexString(digest.digest());
}    
SuperBerry
  • 1,193
  • 1
  • 12
  • 28
  • 1
    This is discussed in some detail elsewhere on SO: https://stackoverflow.com/questions/3450983/will-the-md5-cryptographic-hash-function-output-be-same-in-all-programming-langu – Tom Darby Feb 17 '21 at 05:00
  • 3
    Have you tested your output with a something like http://onlinemd5.com/ ? Then you will know which one is right or wrong... or they are both wrong. – Andy Feb 17 '21 at 05:04
  • Thanks Andy, it seems the c# MD5 is correct.... – SuperBerry Feb 17 '21 at 05:27
  • 1
    I would try some of these implementations until one works: https://stackoverflow.com/questions/304268/getting-a-files-md5-checksum-in-java This one is similar to yours, but they create the hex string differently. Maybe that's the problem: https://stackoverflow.com/a/19427098/1204153 – Andy Feb 17 '21 at 05:39
  • It seems because there are coding different between Linux and Windows... I am still searching a solution – SuperBerry Feb 17 '21 at 06:05

1 Answers1

0

Your bytesToHexString function is wrong. After using the function from here, in this complete example, I get the same result as the Linux md5sum command and`onlinemd5.com as Andy suggested. The best way to handle this is to use a library, such as Apache Commons, that has a function to convert from bytes to a hex string. That way, you offload the work to get it right to a reputable library.

import java.io.File;
import java.io.FileInputStream;
import java.security.MessageDigest;

public class Md5{

    public static String computeMd5(File file) {
        if (!file.isFile()) {
            return null;
        }
        MessageDigest digest = null;
        FileInputStream in = null;
        byte buffer[] = new byte[1024];
        int len;
        try {
            digest = MessageDigest.getInstance("MD5");
            in = new FileInputStream(file);
            while ((len = in.read(buffer, 0, 1024)) != -1) {
                digest.update(buffer, 0, len);
            }
            in.close();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
        return byteArrayToHex(digest.digest());
    }

    public static String byteArrayToHex(byte[] a) {
        StringBuilder sb = new StringBuilder(a.length * 2);
        for(byte b: a)
            sb.append(String.format("%02x", b));
        return sb.toString();
    }

    public static void main(String[] args){
        System.out.println(computeMd5(new File("./text.txt")));
    }

}
john01dav
  • 1,842
  • 1
  • 21
  • 40