MessageDigest MD5算法没有返回我所期望的



我的后脑勺告诉我,我在这里错过了一些明显的东西。

我正在将一个现有的java项目与第三方api集成,该api使用api密钥的md5哈希进行身份验证。它对我不起作用,在调试过程中,我意识到我生成的哈希与他们提供的示例不匹配。我发现一些网站通过字符串创建MD5哈希来检查他们的例子,据我所知,我错了,他们是对的。

例如,根据这个网站,字符串"hello"生成一个散列"5d41402abc4b2a76b9719d911017c592"。(FWIW我对这个网站一无所知,只是它似乎正确地散列了我的例子)。当我通过代码运行它时,我得到:

XUFAKrxLKna5cZ2REBfFkg==

以下是我用来生成md5 hash/string的简单方法

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());
}

上周,我使用了一种非常相似的方法,使用SHA1算法成功地验证了不同的API。我想知道这个问题是否与org.apache.commons.net.util.Base64.encodeBase64String有关…如果只是一些测试,看看字节数组是否正确,但转换的字符串是否错误,我们将非常感谢您的帮助。

例如,根据这个网站,字符串"你好";生成"0"的散列;5d41402abc4b2a76b9719d911017c592";。(FWIW我对这个网站一无所知,只是它似乎正确地散列了我的例子)。当我通过代码运行它时,我得到:

XUFAKrxLKna5cZ2REBfFkg==

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

四个要生成此第三方API所期望的十六进制版本,您可以更改以下内容:

Base64.encodeBase64String(md.digest());

到此:

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

(主要取自StackOverflow的回答)。

但是,您可能需要考虑为此使用外部库。Perception在上面的一条评论中提到了Apache Commons DigestUtils。如果使用该方法,则需要md5hex方法。

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.";
}
}

最新更新