2012-11-30 39 views
5

我脑海中的某个东西告诉我我错过了一些明显的东西。MessageDigest MD5算法没有返回我期望的结果

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

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

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

我用了一个很类似的方法可以在上周使用SHA1算法成功验证不同的API。我想知道如果问题是相关的org.apache.commons.net.util.Base64.encodeBase64String ...任何帮助非常感谢,如果只有一些测试,看看如果byteArray是正确的,但转换的字符串是错误的。

+1

md.digest()应该包含您正在查找的字节,您使用Base64算法进一步对它们进行编码并获得不同的结果 – hoaz

+0

我需要将这些字节转换为http请求的字符串,是否有更好的方法可以做到这一点? – eric

+1

新的字符串(字节[]字节) – Andy

回答

8

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

XUFAKrxLKna5cZ2REBfFkg ==

两者都代表相同的十六字节散列的正确途径。 5d41402abc4b2a76b9719d911017c592将散列的每个字节表示为两个十六进制数字,而XUFAKrxLKna5cZ2REBfFkg==使用Base-64来表示每个三个字节的散列,因为四个个字符。

要生成的十六进制版本,这个第三方API期待,你可以改变这一点:

Base64.encodeBase64String(md.digest()); 

这样:

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

(主要来自this StackOverflow answer拍摄)。

但是,您可能需要考虑使用外部库。 Perception,在上面的评论中提到了Apache Commons DigestUtils。如果你使用它,你需要the md5hex method

+0

将它标记为正确,因为它解决了我的问题,解释了究竟发生了什么,并引用了Perception的关于使用DigestUtils(也适用)的建议。谢谢! – eric

+0

@eric:不客气! – ruakh

2

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