MessageDigest

Java MessageDigest Example

In this post, we are going to discuss about the class java.security.MessageDigest

1. MessageDigest Class

This MessageDigest class provides applications the functionality of a message digest algorithm, such as SHA-1 or SHA-256. Message digests are secure one-way hash functions that take arbitrary-sized data and output a fixed-length hash value.

A message digest is a cryptographic hash function containing a string of digits created by a one-way hashing formula (a cryptographic hash function). This term is also known as a hash value and sometimes as a checksum.

A cryptographic hash function is a hash function which is considered practically impossible to invert, that is, to recreate the input data from its hash value alone. The input data is often called the message, and the hash value is often called the message digest or simply the digest.

The ideal cryptographic hash function has four main properties:

  • It is easy to compute the hash value for any given message.
  • It is infeasible to generate a message that has a given hash.
  • It is infeasible to modify a message without changing the hash.
  • It is infeasible to find two different messages with the same hash.

Cryptographic hash functions have many information security applications, notably in digital signatures, message authentication codes (MACs), and other forms of authentication. They can also be used as ordinary hash functions, to index data in hash tables, for fingerprinting, to detect duplicate data or uniquely identify files, and as checksums to detect accidental data corruption. Indeed, in information security contexts, cryptographic hash values are sometimes called (digital) fingerprints, checksums, or just hash values, even though all these terms stand for more general functions with rather different properties and purposes.

Let’s see an example of using the MessageDigest Class file.

2. Executing some code

App.java

package com.javacodegeeks.examples.messagedigest;

//~--- JDK imports ------------------------------------------------------------

import java.math.BigInteger;

import java.net.URI;

import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

import java.security.MessageDigest;

import java.util.logging.Level;
import java.util.logging.Logger;

public class App {
    private static final Logger logger = Logger.getLogger("App");

    // ========================================================================
    // = Text files to exemplify MessageDigest functionality ==================
    // ========================================================================
    private static final String FILE1 = "file1ToHash.txt";
    private static final String FILE2 = "file2ToHash.txt";
    private static final String FILE3 = "file3ToHash.txt";

    // ========================================================================
    // = Some of the Cryptographic Hash Functions supported by MessageDigest ==
    // = You can choose any of them for this example                         ==
    // ========================================================================
    private static final String MD5    = "MD5";
    private static final String SHA1   = "SHA-1";
    private static final String SHA256 = "SHA-256";

    // ========================================================================
    // = Utility function to get a file located in the classpath ==============
    // ========================================================================
    public URI getFileURI(String fileName) throws Exception {
        URI result = this.getClass().getClassLoader().getResource(fileName).toURI();

        return result;
    }

    public static void main(String[] args) {
        try {
            App app = new App();

            // Instance a MessageDigest
            MessageDigest messageDigest = MessageDigest.getInstance(App.MD5);

            // Files to be cryptographically hashed and compared
            Path   path1      = Paths.get(app.getFileURI(App.FILE1));
            byte[] file1Bytes = Files.readAllBytes(path1);
            Path   path2      = Paths.get(app.getFileURI(App.FILE2));
            byte[] file2Bytes = Files.readAllBytes(path2);
            Path   path3      = Paths.get(app.getFileURI(App.FILE3));
            byte[] file3Bytes = Files.readAllBytes(path3);

            // Digest files content
            byte[] digestedFile1Bytes = messageDigest.digest(file1Bytes);

            messageDigest.reset();

            byte[] digestedFile2Bytes = messageDigest.digest(file2Bytes);

            // The content of both files is EXACTLY the same
            // We can see that the generated hash, is IDENTICAL for both files
            logger.info("Byte representation of File1 content: "
                        + (new BigInteger(1, digestedFile1Bytes)).toString(32));
            logger.info("Byte representation of File2 content: "
                        + (new BigInteger(1, digestedFile2Bytes)).toString(32));
            logger.info(MessageDigest.isEqual(digestedFile1Bytes, digestedFile2Bytes)
                        ? "Identical hashes"
                        : "Different hashes");

            // The content of FILE3 is EXACTLY the same as in FILE1 and FILE2
            // with just and extra 'A' appended at the very end
            // We can see that this is enough to have a total different hash
            messageDigest.reset();

            byte[] digestedFile3Bytes = messageDigest.digest(file3Bytes);

            logger.info("Byte representation of File3 content: "
                        + (new BigInteger(1, digestedFile3Bytes)).toString(32));
            logger.info(MessageDigest.isEqual(digestedFile1Bytes, digestedFile3Bytes)
                        ? "Identical hashes"
                        : "Different hashes");
        } catch (Exception e) {
            logger.log(Level.SEVERE, e.getMessage());
            e.printStackTrace(System.err);
        }
    }
}

Let’s explain the methods used in the previous code

The output of the command

java com.javacodegeeks.examples.resourcebundle.App

should be similar to:

Sep 20, 2014 3:21:14 PM com.javacodegeeks.examples.messagedigest.App main
INFO: Byte representation of File1 content: 2iushamrct9sea3283knvpr4hh
Sep 20, 2014 3:21:14 PM com.javacodegeeks.examples.messagedigest.App main
INFO: Byte representation of File2 content: 2iushamrct9sea3283knvpr4hh
Sep 20, 2014 3:21:14 PM com.javacodegeeks.examples.messagedigest.App main
INFO: Identical hashes
Sep 20, 2014 3:21:14 PM com.javacodegeeks.examples.messagedigest.App main
INFO: Byte representation of File3 content: 6tm9o2f6kpe2rd3m2ue89pi2ul
Sep 20, 2014 3:21:14 PM com.javacodegeeks.examples.messagedigest.App main
INFO: Different hashes

3. Download the Eclipse project of this tutorial:

This was an example of how to set use the MessageDigest Class.

Download
You can download the full source code of this example here : messagedigest.zip

Armando Flores

Armando graduated from from Electronics Engineer in the The Public University Of Puebla (BUAP). He also has a Masters degree in Computer Sciences from CINVESTAV. He has been using the Java language for Web Development for over a decade. He has been involved in a large number of projects focused on "ad-hoc" Web Application based on Java EE and Spring Framework.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Inline Feedbacks
View all comments
Back to top button