Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams MD5 might be unsafe as a one-way security feature, but it is still good for generic checksum applications. rustyx Feb 6, 2015 at 15:57

The MessageDigest class can provide you with an instance of the MD5 digest.

When working with strings and the crypto classes be sure to always specify the encoding you want the byte representation in. If you just use string.getBytes() it will use the platform default. (Not all platforms use the same defaults)

import java.security.*;
byte[] bytesOfMessage = yourString.getBytes("UTF-8");
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] theMD5digest = md.digest(bytesOfMessage);

If you have a lot of data take a look at the .update(xxx) methods which can be called repeatedly. Then call .digest() to obtain the resulting hash.

“LATIN1” != “ASCII” (or “US-ASCII”). ASCII is a 7-bit character set, Latin1 is an 8-bit character set. They are not the same. – Bombe Jan 7, 2009 at 7:57 Better yet, where possible use yourString.getBytes(StandardCharsets.UTF_8). This prevents handling an UnsupportedEncodingException. – Hummeling Engineering BV Mar 7, 2019 at 10:28

You need java.security.MessageDigest.

Call MessageDigest.getInstance("MD5") to get a MD5 instance of MessageDigest you can use.

The compute the hash by doing one of:

  • Feed the entire input as a byte[] and calculate the hash in one operation with md.digest(bytes).
  • Feed the MessageDigest one byte[] chunk at a time by calling md.update(bytes). When you're done adding input bytes, calculate the hash with md.digest().
  • The byte[] returned by md.digest() is the MD5 hash.

    One thing that's not mentioned here, and caught me by surprise. The MessageDigest classes are NOT thread safe. If they're going to be used by different threads, just create a new one, instead of trying to reuse them. – mjuarez Mar 7, 2013 at 6:34 It uses multiple methods to mutate its internal state. How can the lack of thread safety be surprising at all? – Bombe Apr 25, 2013 at 7:57 @DanBarowy well, you are mutating it (i.e. calling methods that do not return values but cause other methods to return different values) so until proven otherwise you should always assume that it’s not thread-safe to do so. – Bombe Jul 9, 2014 at 18:17 @Traubenfuchs MessageDigest allows you to input the data in chunks. That wouldn't be possible with a static method. Although you can argue they should have added one anyway for convenience when you can pass all the data at once. – user253751 Aug 16, 2015 at 12:39

    If you actually want the answer back as a string as opposed to a byte array, you could always do something like this:

    String plaintext = "your text here";
    MessageDigest m = MessageDigest.getInstance("MD5");
    m.reset();
    m.update(plaintext.getBytes());
    byte[] digest = m.digest();
    BigInteger bigInt = new BigInteger(1,digest);
    String hashtext = bigInt.toString(16);
    // Now we need to zero pad it if you actually want the full 32 chars.
    while(hashtext.length() < 32 ){
      hashtext = "0"+hashtext;
                    @BalusC: Not true, the BigInteger.toString method will return the full number in the base specified. 0x0606 will be printed as 606, just trailing zeros are omitted,
    – Spidey
                    Aug 29, 2010 at 22:29
                    Minor nitpick: m.reset() isn't necessary right after calling getInstance.  More minor: 'your text here' requires double-quotes.
    – David Leppik
                    Apr 19, 2011 at 15:28
                    From Java 11 on, you can use hashtext = "0".repeat(32 - hashtext.length()) + hashtext instead of the while, so the editors won't give you a warning that you're doing string concatenation inside a loop.
    – tom
                    May 14, 2019 at 13:29
                    Instead of m.update(plaintext.getBytes()); I would recommend specifying the encoding. such as m.update(plaintext.getBytes("UTF-8"));  getBytes() does not guarantee the encoding and may vary from system to system which may result in different MD5 results between systems for the same String.
    – user1819780
                    Mar 27, 2020 at 5:35
                    In particular, the methods which return "safe" encoded representations of the byte data in string form.
    – Rob
                    Jan 7, 2009 at 19:21
                    However there is no easy way to get the DigestUtils class into your project without adding a ton of libs, or porting the class "per hand" which requires at least two more classes.
    – iuiz
                    Jul 23, 2011 at 20:52
                    Should be in the central Maven repositories, unless I'm going crazy: groupId=commons-codec artifactId=commons-codec version=1.5
    – Nick Spacek
                    Oct 12, 2011 at 17:10
    
    public String MD5(String md5) {
       try {
            java.security.MessageDigest md = java.security.MessageDigest.getInstance("MD5");
            byte[] array = md.digest(md5.getBytes());
            StringBuffer sb = new StringBuffer();
            for (int i = 0; i < array.length; ++i) {
              sb.append(Integer.toHexString((array[i] & 0xFF) | 0x100).substring(1,3));
            return sb.toString();
        } catch (java.security.NoSuchAlgorithmException e) {
        return null;
    

    on the site below, I take no credit for it, but its a solution that works! For me lots of other code didnt work properly, I ended up missing 0s in the hash. This one seems to be the same as PHP has. source: http://m2tec.be/blog/2010/02/03/java-md5-hex-0093

    You should specify the encoding to be used in getBytes(), otherwise your code will get different results on different platforms/user settings. – Paŭlo Ebermann Jul 3, 2011 at 21:57 @PaŭloEbermann does MessageDigest.getInstance("MD5"); not enough? I tried to add "MD5" in getBytes() but it returned an error – Blaze Tama Feb 19, 2014 at 5:29 @BlazeTama "MD5" is not an encoding, it is a message digest algorithm (and not one which should be used in new applications). An encoding is an algorithm pair which transforms bytes to strings and strings to bytes. An example would be "UTF-8", "US-ASCII", "ISO-8859-1", "UTF-16BE", and similar. Use the same encoding as every other party which calculates a hash of this string, otherwise you'll get different results. – Paŭlo Ebermann Feb 21, 2014 at 19:48 For an example of the character set... (use UTF-8, that is the best and most compatible in my opinion)... byte[] array = md.digest(md5.getBytes(Charset.forName("UTF-8"))); – Richard Nov 25, 2014 at 1:56 Since its not my solution, and I didnt test all scenarios myself, I will leave it unchanged, although I think specifiying encoding etc is probably a good idea. – dac2009 Jul 8, 2019 at 10:45

    Here is how I use it:

    final MessageDigest messageDigest = MessageDigest.getInstance("MD5");
    messageDigest.reset();
    messageDigest.update(string.getBytes(Charset.forName("UTF8")));
    final byte[] resultByte = messageDigest.digest();
    final String result = new String(Hex.encodeHex(resultByte));
    

    where Hex is: org.apache.commons.codec.binary.Hex from the Apache Commons project.

    If you use Apache Commons Codec anyway you can use: commons.apache.org/codec/api-release/org/apache/commons/codec/… – squiddle Oct 25, 2010 at 15:10

    I've found this to be the most clear and concise way to do it:

    MessageDigest md5 = MessageDigest.getInstance("MD5");
    md5.update(StandardCharsets.UTF_8.encode(string));
    return String.format("%032x", new BigInteger(1, md5.digest()));
                    Beware this won't work for Android if you're using API level < 19, but you just need to change the second line with md5.update(string.getBytes("UTF-8")); This will add yet another checked exception to handle, though...
    – Fran Marzoa
                    Feb 20, 2018 at 20:27
    

    I just downloaded commons-codec.jar and got perfect php like md5. Here is manual.

    Just import it to your project and use

    String Url = "your_url";
    System.out.println( DigestUtils.md5Hex( Url ) );
    

    and there you have it.

    This is the method that provides the same return value as the MySQL function md5(str). A lot of the other answers did return other values. – rwitzel Mar 18, 2015 at 14:54 This doesn't work right on Android because Android bundles commons-codec 1.2, for which you need this workaround: stackoverflow.com/a/9284092/2413303 – EpicPandaForce Mar 19, 2015 at 10:22

    No need to make it too complicated.
    DigestUtils works fine and makes you comfortable while working with md5 hashes.

    DigestUtils.md5Hex(_hash);
    
    DigestUtils.md5(_hash);
    

    Either you can use any other encryption methods such as sha or md.

    Found this solution which is much cleaner in terms of getting a String representation back from an MD5 hash.

    import java.security.*;
    import java.math.*;
    public class MD5 {
        public static void main(String args[]) throws Exception{
            String s="This is a test";
            MessageDigest m=MessageDigest.getInstance("MD5");
            m.update(s.getBytes(),0,s.length());
            System.out.println("MD5: "+new BigInteger(1,m.digest()).toString(16));
    

    The code was extracted from here.

    I just found out that in some cases this only generates 31 characters long MD5 sum, not 32 as it should be – kovica Mar 29, 2013 at 14:09 @kovica this is because, the starting zeros get truncated if I remember right.. String.format("%032x", new BigInteger(1, hash)); This should solve this. 'hash' is the byte[] of the hash. – Heshan Perera Apr 1, 2013 at 5:10 Unless I'm mistaken this returns always in uppercase which will not align with md5's made without using hex. Not even really sure it is a true md5 – walshie4 Jun 29, 2017 at 2:00

    Another option is to use the Guava Hashing methods:

    Hasher hasher = Hashing.md5().newHasher();
    hasher.putString("my string");
    byte[] md5 = hasher.hash().asBytes();
    

    Handy if you are already using Guava (which if you're not, you probably should be).

    @KurtAlfredKluever don't forget to insert the charset like 'Hashing.md5().hashString("my string", Charsets.UTF_8).asBytes()' – Justin Apr 21, 2016 at 14:14

    I have a Class (Hash) to convert plain text in hash in formats: md5 or sha1, simillar that php functions (md5, sha1):

    public class Hash {
         * @param txt, text in plain format
         * @param hashType MD5 OR SHA1
         * @return hash in hashType 
        public static String getHash(String txt, String hashType) {
            try {
                        java.security.MessageDigest md = java.security.MessageDigest.getInstance(hashType);
                        byte[] array = md.digest(txt.getBytes());
                        StringBuffer sb = new StringBuffer();
                        for (int i = 0; i < array.length; ++i) {
                            sb.append(Integer.toHexString((array[i] & 0xFF) | 0x100).substring(1,3));
                        return sb.toString();
                } catch (java.security.NoSuchAlgorithmException e) {
                    //error action
                return null;
        public static String md5(String txt) {
            return Hash.getHash(txt, "MD5");
        public static String sha1(String txt) {
            return Hash.getHash(txt, "SHA1");
    

    Testing with JUnit and PHP

    PHP Script:

    echo 'MD5 :' . md5('Hello World') . "\n"; echo 'SHA1:' . sha1('Hello World') . "\n";

    Output PHP script:

    MD5 :b10a8db164e0754105b7a99be72e3fe5
    SHA1:0a4d55a8d778e5022fab701977c5d840bbc486d0
    

    Using example and Testing with JUnit:

        public class HashTest {
        @Test
        public void test() {
            String txt = "Hello World";
            assertEquals("b10a8db164e0754105b7a99be72e3fe5", Hash.md5(txt));
            assertEquals("0a4d55a8d778e5022fab701977c5d840bbc486d0", Hash.sha1(txt));
    

    Code in GitHub

    https://github.com/fitorec/java-hashes

    try { MessageDigest m = MessageDigest.getInstance("MD5"); m.update(s.getBytes(), 0, s.length()); BigInteger i = new BigInteger(1,m.digest()); return String.format("%1$032x", i); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); return null;

    There is a DigestUtils class in Spring also:

    http://static.springsource.org/spring/docs/3.0.x/javadoc-api/org/springframework/util/DigestUtils.html

    This class contains the method md5DigestAsHex() that does the job.

    BTW: The performance of this is much better then using BigInteger to create the hex string representation. – James Apr 17, 2018 at 9:37

    You can try following. See details and download codes here: http://jkssweetlife.com/java-hashgenerator-md5-sha-1/

    import java.security.MessageDigest;
    import java.security.NoSuchAlgorithmException;
    public class MD5Example {
    public static void main(String[] args) throws Exception {
        final String inputString = "Hello MD5";
        System.out.println("MD5 hex for '" + inputString + "' :");
        System.out.println(getMD5Hex(inputString));
    public static String getMD5Hex(final String inputString) throws NoSuchAlgorithmException {
        MessageDigest md = MessageDigest.getInstance("MD5");
        md.update(inputString.getBytes());
        byte[] digest = md.digest();
        return convertByteToHex(digest);
    private static String convertByteToHex(byte[] byteData) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < byteData.length; i++) {
            sb.append(Integer.toString((byteData[i] & 0xff) + 0x100, 16).substring(1));
        return sb.toString();
    

    Bombe's answer is correct, however note that unless you absolutely must use MD5 (e.g. forced on you for interoperability), a better choice is SHA1 as MD5 has weaknesses for long term use.

    I should add that SHA1 also has theoretical vulnerabilities, but not as severe. The current state of the art in hashing is that there are a number of candidate replacement hash functions but none have yet emerged as the standard best practice to replace SHA1. So, depending on your needs you would be well advised to make your hash algorithm configurable so it can be replaced in future.

    Could you point me to some resources, where i can read about relative merits and weaknesses of each? – Akshay Jan 6, 2009 at 10:19 Probably the best you can do at the moment is use SHA1 and be ready to replace it in future. You could use newer functions but they have not yet been subject to great amounts of research. You could track online security resources to find out when this changes - for example Bruce Schneier's blog. – frankodwyer Jan 6, 2009 at 10:49 SHA1 is overkill unless you want a cryptographically secure hash, i.e. you don't want the hash to help in reconstructing the original message, nor do you want a clever attacker to create another message which matches the hash. If the original isn't a secret and the hash isn't being used for security, MD5 is fast and easy. For example, Google Web Toolkit uses MD5 hashes in JavaScript URLs (e.g. foo.js?hash=12345). – David Leppik Apr 19, 2011 at 15:14 I found it very useful. It took 15357 ms for a 4.57GB file whereas java inbuilt implementation took 19094 ms. – bkrish May 1, 2016 at 22:37

    I do not know if this is relevant for anyone reading this, but I just had the problem that I wanted to

  • download a file from a given URL and
  • compare its MD5 to a known value.
  • I wanted to do it with JRE classes only (no Apache Commons or similar). A quick web search did not show me sample code snippets doing both at the same time, only each task separately. Because this requires to read the same file twice, I figured it might be worth the while to write some code which unifies both tasks, calculating the checksum on the fly while downloading the file. This is my result (sorry if it is not perfect Java, but I guess you get the idea anyway):

    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.math.BigInteger;
    import java.net.URL;
    import java.nio.ByteBuffer;
    import java.nio.channels.Channels;
    import java.nio.channels.ReadableByteChannel;
    import java.nio.channels.WritableByteChannel;
    import java.security.DigestOutputStream;        // new
    import java.security.MessageDigest;
    import java.security.NoSuchAlgorithmException;
    void downloadFile(String fromURL, String toFile, BigInteger md5)
        throws IOException, NoSuchAlgorithmException
        ReadableByteChannel in = Channels.newChannel(new URL(fromURL).openStream());
        MessageDigest md5Digest = MessageDigest.getInstance("MD5");
        WritableByteChannel out = Channels.newChannel(
            //new FileOutputStream(toFile));  // old
            new DigestOutputStream(new FileOutputStream(toFile), md5Digest));  // new
        ByteBuffer buffer = ByteBuffer.allocate(1024 * 1024);  // 1 MB
        while (in.read(buffer) != -1) {
            buffer.flip();
            //md5Digest.update(buffer.asReadOnlyBuffer());  // old
            out.write(buffer);
            buffer.clear();
        BigInteger md5Actual = new BigInteger(1, md5Digest.digest()); 
        if (! md5Actual.equals(md5))
            throw new RuntimeException(
                "MD5 mismatch for file " + toFile +
                ": expected " + md5.toString(16) +
                ", got " + md5Actual.toString(16)
                    Oh BTW, before anyone except for myself notices how bad my JRE knowledge really is: I just discovered DigestInputStream and DigestOutputStream. I am going to edit my original solution to reflect what I have just learned.
    – kriegaex
                    Jun 26, 2012 at 8:45
    byte[] bytesOfMessage = yourString.getBytes("UTF-8");
    MessageDigest md = MessageDigest.getInstance("MD5");
    byte[] bytesOfDigest = md.digest(bytesOfMessage);
    String digest = DatatypeConverter.printHexBinary(bytesOfDigest).toLowerCase();
    

    Unlike PHP where you can do an MD5 hashing of your text by just calling md5 function ie md5($text), in Java it was made little bit complicated. I usually implemented it by calling a function which returns the md5 hash text. Here is how I implemented it, First create a function named md5hashing inside your main class as given below.

    public static String md5hashing(String text)
        {   String hashtext = null;
                String plaintext = text;
                MessageDigest m = MessageDigest.getInstance("MD5");
                m.reset();
                m.update(plaintext.getBytes());
                byte[] digest = m.digest();
                BigInteger bigInt = new BigInteger(1,digest);
                hashtext = bigInt.toString(16);
                // Now we need to zero pad it if you actually want the full 32 chars.
                while(hashtext.length() < 32 ){
                  hashtext = "0"+hashtext;   
            } catch (Exception e1) 
                // TODO: handle exception
                JOptionPane.showMessageDialog(null,e1.getClass().getName() + ": " + e1.getMessage());   
            return hashtext;     
    

    Now call the function whenever you needed as given below.

    String text = textFieldName.getText();
    String pass = md5hashing(text);
    

    Here you can see that hashtext is appended with a zero to make it match with md5 hashing in PHP.

    For what it's worth, I stumbled upon this because I want to synthesize GUIDs from a natural key for a program that will install COM components; I want to syhthesize so as not to manage GUID lifecycle. I'll use MD5 and then use the UUID class to get a string out of it. (http://stackoverflow.com/questions/2190890/how-can-i-generate-guid-for-a-string-values/12867439 raises this issue).

    In any case, java.util.UUID can get you a nice String from the MD5 bytes.

    return UUID.nameUUIDFromBytes(md5Bytes).toString();
                    actually it accepts not only MD5 bytes array (size == 16). You can pass byte array of any length. It will be converted to MD5 bytes array by means of MD5 MessageDigest (see nameUUIDFromBytes() source code)
    – Ilya Serbis
                    Oct 20, 2017 at 22:18
    

    this one gives the exact md5 as you get from mysql's md5 function or php's md5 functions etc. This is the one I use (you can change according to your needs)

    public static String md5( String input ) {
        try {
            java.security.MessageDigest md = java.security.MessageDigest.getInstance("MD5");
            byte[] array = md.digest(input.getBytes( "UTF-8" ));
            StringBuffer sb = new StringBuffer();
            for (int i = 0; i < array.length; i++) {
                sb.append( String.format( "%02x", array[i]));
            return sb.toString();
        } catch ( NoSuchAlgorithmException | UnsupportedEncodingException e) {
            return null;            
    //Quick MD5 of text
    val text = "MD5 this text!"
    val md5hash1 = digest.digest(text.getBytes).map("%02x".format(_)).mkString
    //MD5 of text with updates
    digest.update("MD5 ".getBytes())
    digest.update("this ".getBytes())
    digest.update("text!".getBytes())
    val md5hash2 = digest.digest().map(0xFF & _).map("%02x".format(_)).mkString
    //Output
    println(md5hash1 + " should be the same as " + md5hash2)
    

    You can generate MD5 hash for a given text by making use of the methods in the MessageDigest class in the java.security package. Below is the complete code snippet,

    import java.security.MessageDigest;
    import java.security.NoSuchAlgorithmException;
    import javax.xml.bind.DatatypeConverter;
    public class MD5HashGenerator 
       public static void main(String args[]) throws NoSuchAlgorithmException
           String stringToHash = "MyJavaCode"; 
           MessageDigest messageDigest = MessageDigest.getInstance("MD5");
           messageDigest.update(stringToHash.getBytes());
           byte[] digiest = messageDigest.digest();
           String hashedOutput = DatatypeConverter.printHexBinary(digiest);
           System.out.println(hashedOutput);
    

    The output from the MD5 function is a 128 bit hash represented by 32 hexadecimal numbers.

    In case, if you are using a database like MySQL, you can do this in a more simpler way as well. The query Select MD5(“text here”) will return the MD5 hash of the text in the bracket.

    public static String getHashMD5(String string) {
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            BigInteger bi = new BigInteger(1, md.digest(string.getBytes()));
            return bi.toString(16);
        } catch (NoSuchAlgorithmException ex) {
            Logger.getLogger(MD5Utils.class
                    .getName()).log(Level.SEVERE, null, ex);
            return "";
    
     import java.math.BigInteger;
     import java.security.MessageDigest;
     import java.security.NoSuchAlgorithmException;
    * MD5 encryption
    * @author Hongten
    public class MD5 {
     public static void main(String[] args) {
         System.out.println(MD5.getMD5("123456"));
      * Use md5 encoded code value
      * @param sInput
      * clearly
      * @ return md5 encrypted password
     public static String getMD5(String sInput) {
         String algorithm = "";
         if (sInput == null) {
             return "null";
         try {
             algorithm = System.getProperty("MD5.algorithm", "MD5");
         } catch (SecurityException se) {
         MessageDigest md = null;
         try {
             md = MessageDigest.getInstance(algorithm);
         } catch (NoSuchAlgorithmException e) {
             e.printStackTrace();
         byte buffer[] = sInput.getBytes();
         for (int count = 0; count < sInput.length(); count++) {
             md.update(buffer, 0, count);
         byte bDigest[] = md.digest();
         BigInteger bi = new BigInteger(bDigest);
         return (bi.toString(16));
    

    There is an article on Codingkit about that. Check out: http://codingkit.com/a/JAVA/2013/1020/2216.html