Java MessageDigest doesn't work

2019-04-02 05:17发布

问题:

I can't make MessageDigest work, the program gives me two error: UnsupportedEncodingException, NoSuchAlgorithmException

 byte[] bytesOfchat_key = "lol".getBytes("UTF-8");
 MessageDigest md = MessageDigest.getInstance("MD5");
 byte[] Digest = md.digest(bytesOfchat_key);

If I throw the errors, it give me ワ￟ᄡ9ᅦヌnp>0xd￉z as response ( 16 chars )

PS: I have used to print the Digest

for (byte b : Digest) {
    System.out.print((char)b);
}

回答1:

md5 returns hexadecimal numbers, so for decoding it to a String you could use

String plaintext = "lol";
MessageDigest m = MessageDigest.getInstance("MD5");
m.reset();
m.update(plaintext.getBytes());
byte[] digest = m.digest();
//Decoding
BigInteger bigInt = new BigInteger(1,digest);
String hashtext = bigInt.toString(16);
while(hashtext.length() < 32 ){
  hashtext = "0"+hashtext;
}


回答2:

The program doesn't give you those errors - you're calling methods which can throw those exceptions, so you need catch blocks for them, or declare that your method throws them too.

The result of a digest is binary data, not text. You should not convert it byte-by-byte to text like this - if you need it as a string, there are two common solutions:

  • Encode each byte as a pair of hex digits
  • Use Base64 encoding on the complete byte array

Each of these can be implemented easily with Apache Commons Codec.

There's nothing wrong with MessageDigest, but I believe you have a flawed understanding of how exceptions work, and how to treat binary data differently from text data.



回答3:

The bytes generated by the MessageDigest don't necessarily represent printable chars. You should display the numeric value of each byte, or transform the byte array into a Base64 string to have something printable.

See apache commons-codec to get an implementation of Base64.

The two exception that you're forced to handle should never happen, because UTF-8 is guaranteed to be supported by any JVM, and the MD5 algorithm is also supported natively by the JVM. You shoud thus wrap your code inside a try catch block like this:

try {
    byte[] bytesOfchat_key = "lol".getBytes("UTF-8");
    MessageDigest md = MessageDigest.getInstance("MD5");
    byte[] Digest = md.digest(bytesOfchat_key);
}
catch (NoSuchAlgorithmException e) {
    throw new RuntimeException("something impossible just happened", e);
}
catch (UnsupportedEncodingException e) {
    throw new RuntimeException("something impossible just happened", e);
}


标签: java md5 digest