2017-01-10 100 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));}這也解決了前導零問題。不知道如何在這些評論中使用代碼......這真的很煩人。 –