开发者

Java MessageDigest doesn't work

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,开发者_JAVA百科 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);
}


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


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.


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


// I had the issue that the hash from API was not generating right.
// Using eclipse it was working correctly but when running the same API as the service runnable jar was causing wrong value to produce.

// it was caused by java as Java take Lower case and upper case letters as different Ascii values and window take them as same, so you need to simply add lower and upper case letters in your bytes to hex convertion.
// I hope this helps everyone.
      
 private static String makeHash(String key_to_hash) {
            try {
                MessageDigest md = MessageDigest.getInstance("SHA1");
                md.reset();
                md.update(key_to_hash.getBytes(Charset.forName("UTF-8")));
                return bytesToHex(md.digest());
            } catch (Exception ex) {
                ex.printStackTrace();
            }
            return null;
        }
    
        
    
private static String bytesToHex(byte[] b) {
                char hexDigit[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
                        'a', 'b', 'c', 'd', 'e', 'f','A', 'B', 'C', 'D', 'E', 'F' };
                StringBuffer buf = new StringBuffer();
                for (int j = 0; j < b.length; j++) {
                    buf.append(hexDigit[(b[j] >> 4) & 0x0f]);
                    buf.append(hexDigit[b[j] & 0x0f]);
                }
                return buf.toString();
            }
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜