2017-01-10 1 views
1

からMD5ハッシュを生成するこの問題の解決策を見つけましたherechar []

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

[この回答](http://stackoverflow.com/a/421696/369)ゼロを単純に左パディングを示唆している - よりよい解決策があるかどうかはわかりません。 – Blorgbeard

+0

@Blorgbeardこのポストをリンクしてくれてありがとうございます。問題の解決策がたくさんあるようです。もう一つは他より安全ですか? –

+3

MD5を安全にする必要がある場合は、アルゴリズムを切り替える必要があります。これらのハッシュで実際に何をしていますか? – Blorgbeard

答えて

4

このタスクにBigIntegerを使用する必要はありません。バイト配列を16進文字列に変換する方法を書いてください。

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));}これは先行ゼロ問題も解決します。これらのコメントでコードを使用する方法がわからない...これは本当に面倒です。 –