消息摘要 MD5 算法未返回我期望的结果

9

我脑海里有一些东西在告诉我,我在这里忽略了一些显而易见的东西。

我正在将一个现有的Java项目与一个使用API密钥的MD5哈希进行身份验证的第三方API集成。但是它对我不起作用,在调试期间,我意识到我生成的散列与他们提供的示例不匹配。我找到了一些网站,可以从字符串中创建MD5哈希以检查他们的示例,据我所知,我是错误的,他们是正确的。

例如,根据此网站,字符串“hello”生成哈希值“5d41402abc4b2a76b9719d911017c592”。(顺便说一句,除了它似乎可以正确地散列我拥有的示例之外,我对这个网站一无所知)。当我运行我的代码时,我得到:

XUFAKrxLKna5cZ2REBfFkg==

这是我用于生成MD5哈希/字符串的简单方法:

private String md5(String md5Me) throws Exception {
    MessageDigest md = MessageDigest.getInstance("MD5");
    md.reset();
    md.update(md5Me.getBytes("UTF-8"));

    return Base64.encodeBase64String(md.digest());
}

上周我使用了非常相似的方法成功地验证了另一个API,该API使用SHA1算法。我在想这个问题是否与org.apache.commons.net.util.Base64.encodeBase64String有关... 如能提供任何帮助将不胜感激,即使只是对byteArray进行测试以确定是否正确,但转换后的字符串是错误的。


1
md.digest()应包含您要查找的字节,您可以使用Base64算法进一步编码它们,并获得不同的结果。 - hoaz
我需要将这些字节转换为字符串以进行http请求,有更好的方法吗? - eric
1
新的字符串(byte[] bytes) - Andy
1
我猜问题在于不同的文本编码。 - Momo
1
如果您可以使用外部库,Apache Commons DigestUtils 可以为您创建 MD5 哈希值,并已在许多应用程序中进行了测试。 - Perception
DigestUtils.md5Hex 给了我正确的字符串。 - eric
2个回答

9
例如,根据这个网站,字符串“hello”生成哈希值“5d41402abc4b2a76b9719d911017c592”。(顺便说一句,除了它似乎可以正确地哈希我拥有的示例之外,我对这个网站一无所知)。当我在我的代码中运行它时,我得到:

XUFAKrxLKna5cZ2REBfFkg==

两种表示相同十六字节哈希值的方法都是正确的。5d41402abc4b2a76b9719d911017c592将哈希的每个字节表示为两个十六进制数字,而XUFAKrxLKna5cZ2REBfFkg==使用Base-64表示哈希的每三个字节为四个字符。

要生成第三方API期望的十六进制版本,可以更改以下内容:
Base64.encodeBase64String(md.digest());

转换为:

String.format("%032x", new BigInteger(1, md.digest()));

这段内容主要来自于这个StackOverflow答案

然而,你可能想考虑使用一个外部库来完成这个任务。如上方评论中提到的Perception,推荐使用Apache Commons DigestUtils。如果你选择使用它,你需要使用md5hex方法


将此标记为正确,因为它解决了我的问题,解释了到底发生了什么,并引用了Perception的建议使用DigestUtils(它也起作用)。谢谢! - eric

3

MD5哈希算法是核心Java API的一部分,因此不需要任何外部库。以下是我用来使用MD5加密密码的方法。

import java.security.MessageDigest;

/**
 * Use to encrypt passwords using MD5 algorithm
 * @param password should be a plain text password.
 * @return a hex String that results from encrypting the given password.
 */
public static String encryptPassword(String password) {
    try {
        MessageDigest md = MessageDigest.getInstance("MD5");
        md.update(password.getBytes());

        byte byteData[] = md.digest();

        StringBuffer hexString = new StringBuffer();
        for (int i=0;i<byteData.length;i++) {
            String hex=Integer.toHexString(0xff & byteData[i]);
            if(hex.length()==1) hexString.append('0');
            hexString.append(hex);
        }
        return hexString.toString();
    }
    catch(java.security.NoSuchAlgorithmException missing) {
        return "Error.";
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接