# Java Cryptographic Hash Functions

A cryptographic hash function is an algorithm that can be run on data such as an **individual file** or a **password** to produce a value called a **digest**.

The main purpose of the cryptographic hash function is to **verify the authenticity of a piece of data**.

Two files can be assumed to be identical only if the checksums generated from each file, using the same cryptographic hash function, are identical.

**SHA-0**, **SHA-1**, **SHA-2**, and **SHA-3** are some common **Secure Hash Algorithm (SHA)** family of cryptographic hash functions designed by the **National Security Agency**. Apart from the SHA family of hash functions, there are **MD2**, **MD4**, **MD5** and **MD6** common **Message-Digest Algorithm** family of cryptographic hash functions.

The term **“hash function”** is generic which can refer to **cryptographic hash** functions and the **cyclic redundancy check (CRC) hash** functions.

Among the SHA family of hash functions and MD family of hash functions, only a few cryptographic hash functions like **SHA-256 (SHA-2 family)**, **SHA-512 (SHA-2 family)**, **MD5** are the widely used ones.

It is always a trade-off between security and performance, some algorithms are more secure but more performance intense (takes comparatively more time to compute the hash value and also resource-intensive computations). The decision of choosing a proper hashing algorithm is always subjective to the scenario addressed and there are no definite rules.Each of the cryptographic hash functions has its own pros and cons.

The SHA-2 family of cryptographic hash functions consists of 6 hash functions.

- SHA-224, with 224-bit hash values
- SHA-256, with 256-bit hash values
- SHA-384, with 384-bit hash values
- SHA-512, with 512-bit hash values
- SHA-512/224, with 512-bit hash values
- SHA-512/256, with 512-bit hash values

Among these, SHA-256 and SHA-512 are the most commonly accepted and used hash functions computed with 32-bit and 64-bit words, respectively. SHA-224 and SHA-384 are truncated versions of SHA-256 and SHA-512 respectively, computed with different initial values.

In this article let’s explore implementing **SHA-1**, **SHA-256**, **SHA-512** and **MD5** cryptographic hash functions in Java.

Java provides **MessageDigest Class** under the **java.security** package to calculate the cryptographic hash value of a text using one of the following hash functions:

- MD2
- MD5
- SHA-1
- SHA-224
- SHA-256
- SHA-384
- SHA-512

The **JavaHash** class is a generic implementation to invoke the **MessageDigest** class instance with the desired input text and the cryptographic algorithm. The following different hash codes are generated for the input text “InputMessage”.

As you can see from the above output

MD5 hash takes 32 characters — 128 bits length

SHA1 hash takes 40 characters — 160 bits length

SHA256 hash takes 64 characters — 256 bits length (As the name implies)

SHA512 hash takes 128 characters — 512 bits length (As the name implies)

# Choosing a cryptographic hash function

There are a few key aspects we need to consider when choosing a cryptographic hash function.

All the cryptographic hash functions are **one-way functions**. Which means they are irreversible. So it is impossible to reverse the input text from the hash code generated. But still there can be dictionary attacks performed based on the list of popular hashes against the input texts to guess the input text. This can be avoided by selecting an input text which is strong enough.

## Hash Collision

The only way a cryptographic hashing can be broken is by creating **hash collisions** in the hashing algorithm. The attacker forges a fake input text which could create the same cryptographic hash code to match the actual input text. Due to the lesser amount of bits, SHA-1 and MD5 hash algorithms are found to be vulnerable to hash collisions thus leaving a backdoor to the attackers. So, when choosing a hashing algorithm always consider the hash collision (for how long this algorithm will be safe from a hash collision)

## Computational Complexity

Some hashing algorithms might provide better security but might be resource-intensive and take longer times to compute the hash values.

Depending on the requirement some operations like comparing the individual file hashes might need to generate the hash in a short period as there may be a huge amount of files to be checked.

While the hash function selected to generate a hash for the password needs to be computationally complex and take a long time, to prevent attackers from brute-forcing random passwords.

Hope you enjoyed the blog, Thanks for reading. Cheers!!!