2017-01-10 126 views
1

我找到了解决这个问题here的解决方案。从char生成MD5散列[]

private byte[] toBytes(char[] chars) { 
    CharBuffer charBuffer = CharBuffer.wrap(chars); 
    ByteBuffer byteBuffer = Charset.forName("UTF-8").encode(charBuffer); 
    byte[] bytes = Arrays.copyOfRange(byteBuffer.array(), 
      byteBuffer.position(), byteBuffer.limit()); 
    Arrays.fill(charBuffer.array(), '\u0000'); // clear sensitive data 
    Arrays.fill(byteBuffer.array(), (byte) 0); // clear sensitive data 
    return bytes; 
} 

char[] stringChars = "String".toCharArray(); 
byte[] stringBytes = toBytes(stringChars); 

MessageDigest md = MessageDigest.getInstance("MD5"); 
md.update(stringBytes); 
String stringHash = new BigInteger(1, md.digest()).toString(16); 

Arrays.fill(stringChars, '\u0000'); 
Arrays.fill(stringBytes, (byte) 0); 

但它似乎有一个错误,我不知道它在哪里或如何发生。

问题是这一部分,我想:

String hashedPass = new BigInteger(1, md.digest()).toString(16); 

以上代码的输出给出字符串:

String = "9a9cce201b492954f0b06abb081d0bb4"; 
Correct MD5 of above string = "0e67b8eb546c322eeb39153714162ceb", 
The code above though gives = "e67b8eb546c322eeb39153714162ceb"; 

这似乎是一个MD5的前导零丢失。

+0

[This answer](http://stackoverflow.com/a/421696/369)建议简单左填充零 - 我不知道是否有更好的解决方案。 – Blorgbeard

+0

@Blorgbeard非常感谢你链接那篇文章,它似乎有很多不同的(工作)解决方案的问题。比另一个更安全吗? –

+3

如果您正在使用MD5进行需要安全的操作,则应该切换算法。你用这些哈希究竟在做什么? – Blorgbeard

回答

4

您不必为此任务使用BigInteger,只需编写一个将字节数组转换为十六进制字符串的方法即可。

static String hexEncode(byte [] data) { 
    StringBuilder hex = new StringBuilder(); 
    for (byte b : data) hex.append(String.format("%02x", b)); 
    return hex.toString(); 
} 

String hash = hexEncode(md.digest()); 
+0

非常感谢!我现在用这个:StringBuffer sb = new StringBuffer(); for(byte b:digest){sb.append(String.format(“%02x”,b&0xff));}这也解决了前导零问题。不知道如何在这些评论中使用代码......这真的很烦人。 –