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
public static MessageDigest getInstance(String algorithm) throws NoSuchAlgorithmException
– Returns a MessageDigest object that implements the specified digest algorithm.public byte[] digest()
– Completes the hash computation by performing final operations such as padding. The digest is reset after this call is made.public void reset()
– Resets the digest for further use.public static boolean isEqual(byte[] digesta, byte[] digestb)
– Compares two digests for equality. Does a simple byte compare.
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.
You can download the full source code of this example here : messagedigest.zip