Java和C#之间的MD5不同

时间:2015-08-15 10:32:25

标签: java c# hash cryptography md5

我想比较来自同一文件的MD5哈希值。该文件通过来自Android的HTTP POST作为byte []发送,我还计算了从.NET服务器收到的哈希值,我再次计算哈希值,然后想要比较它们。

问题是,对于同一个文件,我会得到不同的哈希......

Java代码

FileInputStream fileInputStream = null;

byte[] bFile = new byte[(int) file.length()];

try {

    fileInputStream = new FileInputStream(file);
    fileInputStream.read(bFile);

} catch (Exception e) {
    e.printStackTrace();
}

try {
    MessageDigest md = MessageDigest.getInstance("MD5");

    int read = 0;
    while((read = fileInputStream.read(bFile)) != -1) {
        md.update(bFile, 0, read);
    }
    fileInputStream.close();

    byte[] mdBytes = md.digest();

    StringBuffer sb = new StringBuffer();
    for(int i=0; i < mdBytes.length; ++i) {
        sb.append(Integer.toString((mdBytes[i] & 0xff) + 0x100, 16).substring(1));
    }

    // generated MD5 is d41d8cd98f00b204e9800998ecf8427e


} catch (NoSuchAlgorithmException e) {
    e.printStackTrace();
} catch (IOException e) {
    e.printStackTrace();
}

C#代码

using (var md5 = MD5.Create())
{
    using (var stream = File.OpenRead(filePath))
    {
        string hexString = ToHex(md5.ComputeHash(stream), false);

        // Generated MD5 is d167df114a478809ef71fb7e10c40f8c
    }
}

public string ToHex(byte[] bytes, bool upperCase)
{
    StringBuilder result = new StringBuilder(bytes.Length * 2);

    for (int i = 0; i < bytes.Length; i++)
        result.Append(bytes[i].ToString(upperCase ? "X2" : "x2"));

    return result.ToString();
}

更新

我试图将Java代码更改为

StringBuffer sb = new StringBuffer();
for(int i=0; i < mdBytes.length; ++i) {
    sb.append(String.format("%02x", mdBytes[i]));
}

结果总是一样......

2 个答案:

答案 0 :(得分:3)

首先,通过使用一个(或多个)免费提供的工具中的一个(或多个)来计算MD5哈希,并查看您的C#或您的Java代码是否正确(可能两者都是错误的,好的:-)),将您的工作减半。

然后我们会看到。

更新

在Java情况下,您将数据读入字节数组;之后你使用相同的流(已经是EOF),因此从不调用md.update

更新2:

所以,写一下

[...]
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(bFile, 0 , bFile.length);
byte[] mdBytes = md.digest();
[...]

你的基本上没事。顺便说一句,将字节数组转换为十六进制字符串的有趣技术...... :-)你可能想找一个更好的方法,但是......

答案 1 :(得分:3)

读取文件流后,必须回到流的开头才能正确计算哈希值。