Open In App

# Cryptographic Hash Function in Java

Cryptographic Hash is a Hash function that takes random size input and yields a fixed-size output. It is easy to calculate but challenging to retrieve the original data. It is strong and difficult to duplicate the same hash with unique inputs and is a one-way function so revert is not possible. Hashing is also known by different names such as Digest, Message Digest, Checksum, etc.

### Properties Of Cryptography Hash Function

The ideal cryptographic hash function has the following main properties:

1. Deterministic: This means that the same message always results in the same hash.
2. Quick: It is quick to compute the hash value for any given message.
3. Avalanche Effect: This means that every minor change in the message results in a major change in the hash value.
4. One-Way Function: You cannot reverse the cryptographic hash function to get to the data.
5. Collision Resistance: It is infeasible to find two different messages that produce the same hash value.
6. Pre-Image Resistance: The hash value shouldn’t be predictable from the given string and vice versa.
7. Second Pre-Image Resistance: Given an input, it should be difficult to find another input that has the same hash value.

We often hear the term Cracking a Hash, there are a couple of ways to do that:

• Find an algorithm to generate a collision between two hashes. The more advance the algorithm is, the more difficult it is to crack the hash.
• Another way is to find an algorithm to identify a unique and different input that will produce a given hash. It is similar to a collision, but instead of colliding, we are focusing on finding the input using an algorithm.
• Some common hashes we still use today that are considered “cracked” from a cryptographic point of view are MD5(Message-Digest Algorithm) and SHA-1(Secure Hash Algorithm 1). Keep in mind that these are technically broken Hashes and never use for security purposes.

### How to create a Cryptographic Hash

• Create a random salt value using SecureRandom class, SecureRandom class generates strong random values. The engineNextBytes(byte[] bytes) method is used to generate a user-specified number of random bytes.
• Convert two sets of bytes into one using ByteArrayOutputStream class and create it to ByteArray.
• Create an instance of a message-digest passing SHA2_ALGORITHM which returns a hash of the given input value.
• UUID is used to genmessage-digested to a string and passed as input.
• The returned object can be converted to a hex binary format using DatatypeConverter.

## Java

 // Java program to demonstrate// how to create a Hash package java_cryptography; import java.io.ByteArrayOutputStream;import java.security.MessageDigest;import java.util.UUID;import javax.xml.bind.DatatypeConverter;import sun.security.provider.SecureRandom; public class Hashing {     // Initializing the final string variable    private static final String SHA2_ALGORITHM        = "SHA-256";     // Creating a random salt value to prevent    // attacks from the Rainbow table.    public static byte[] Creating_Random_Salt()    {        byte[] salt = new byte[16];        SecureRandom secure_random            = new SecureRandom();        secure_random.engineNextBytes(salt);        return salt;    }     // Creating hash value using input value    // and salt using the SHA2 Algorithm.    public static byte[] Creating_SHA2_Hash(        String input, byte[] salt) throws Exception    {        ByteArrayOutputStream byte_Stream            = new ByteArrayOutputStream();         byte_Stream.write(salt);        byte_Stream.write(input.getBytes());        byte[] valueToHash            = byte_Stream.toByteArray();        MessageDigest messageDigest            = MessageDigest                  .getInstance(SHA2_ALGORITHM);        return messageDigest            .digest(valueToHash);    }     public static void main(String args[])        throws Exception    {         // Calling the function Creating_Random_Salt()        // to generate a random salt value        byte[] salt = Creating_Random_Salt();        System.out.println(            "SALT_VALUE: "            + DatatypeConverter.printHexBinary(salt));        String valueToHash            = UUID.randomUUID().toString();         // Generating first hash with the salt        byte[] hash1            = Creating_SHA2_Hash(valueToHash, salt);         // Generating second hash with exact salt        // to check if we get the same hash.        byte[] hash2            = Creating_SHA2_Hash(valueToHash, salt);         // Print first and the second hash value        System.out.println(            "HASH1_VALUE: "            + DatatypeConverter                  .printHexBinary(hash1));        System.out.println(            "HASH2_VALUE: "            + DatatypeConverter                  .printHexBinary(hash2));    }}

Note: Salt is a random value added to the input data(passwords) to defend against pre-computed hash attacks such as Rainbow tables.

Output:

SALT_VALUE: A96BB94B1FDACDD9B5FDDFFF2E173366 HASH1_VALUE: 53C77F310EEBCBDA585E9458BCA02715555624D9838190AC7DB5F7FA424C8429 HASH2_VALUE: 53C77F310EEBCBDA585E9458BCA02715555624D9838190AC7DB5F7FA424C8429

### How to create Cryptographic Hashing Passwords

As we have seen how to generate a Hash now, let us use Bcrypt to hash a password. Do not use broken Hashing algorithms for Hashing Passwords. Bcrypt is a password Hashing function based on Blowfish Cipher.

Approach:

• Pass the password to hashpw function which is in Bcrypt class which can also generate the salt by itself and returns a string.
• Verify if the password hash and password are really matching using the checkpw() function. It returns a Boolean value.

Code: