MD5 & SHA Hashing Algorithm

Overview on MD5 Algorithm

The MD5 Message-Digest Algorithm is a widely used cryptographic hash function that produces a 128 bit (16-byte) hash value. It is very simple and straight forward; the basic idea is to map data sets of variable length to data sets of a fixed length. After using MD5, generated hash is typically a 32-digit hexadecimal number .In order to do this, the input message is split into chunks of 512-bit blocks. Now these blocks are processed by the MD5 algorithm, which operates in a 128-bit state, and the result will be a 128-bit hash value.

Here, the data to be encoded is often called the “message” and the generated hash value is called the message digest “digest”.

MD5 is it is very fast, and easy to learn and implement but It generates fairly week hashes which is not too much secure. As we know storing the text password with hashing is most dangerous thing for application security today.

MD5 can be made more secure using salt: Salt is some randomly generated text,which is appended to password before obtaining hash,Like : Salt + Password + Salt = Hash.

Example based on MD5 using Java with  Salt:

public class SaltedMD5{
 Public static void main (String [] args) throws NoSuchAlgorithmException, NoSuchProviderException{
    String password = "userPassword";
    byte[] salt = getSalted();
    String securePassword = getSaltPassword(password, salt);
    System.out.println(securePassword);
 }
//Add salt
private static byte[] getSalted() throws NoSuchAlgorithmException, NoSuchProviderException{
   SecureRandom sr = SecureRandom.getInstance("SHA1PRNG", "SUN");
   byte[] salt = new byte[16];
   sr.nextBytes(salt);
return salt;
 }
  
private static String getSaltPassword(String password, byte[] salt){
   String generatedPassword = null;
   try {
      MessageDigest md = MessageDigest.getInstance("MD5");
      md.update(salt);
      byte[] bytes = md.digest(passwordToHash.getBytes());
      StringBuilder sb = new StringBuilder();
      for(int i=0; i< bytes.length ;i++){
      sb.append(Integer.toString((bytes[i] & 0xff) + 0x100, 16).substring(1));
    }
      generatedPassword = sb.toString();
   }catch (NoSuchAlgorithmException e) {
      e.printStackTrace();
   }
return generatedPassword;
  }
}

Note: Please remember that once this password hash is generated and stored in database, you cannot convert it back to original password.
MD5 generates 128 bit hash. To make it more secure, use SHA algorithm which generate hashes from 160-bit to 512-bit long. 512-bit is strongest.

SHA Hashing Algorithm

SHA stands for Secure Hash Algorithm. It is very similar to MD5 except it generates more strong hashes. The SHA hash functions are a set of cryptographic hash functions designed by the National Security Agency (NSA) and published by the NIST as a U.S. Federal Information Processing Standard. Robust and fast security functionality is basic tenant for secure computer transactions. Hashing algorithms have long been the poor-man of the community, with their security receiving less attention than standard encryption algorithms and with little attention paid to their speed.The three SHA algorithms are structured differently and are distinguished as SHA-0,SHA-1,and SHA-2.

What is SHA Hashing?

The SHA (Secure Hash Algorithm) is one of a number of cryptographic hash functions. A cryptographic hash is like a signature for a text or a data file. SHA-256 algorithm generates an almost-unique, fixed size 256-bit (32-byte) hash.

We can say in other words:
Hashing algorithms are mathematical functions that convert input text values to a hash digest. Even the smallest change of the input text produces radically different hashed values. SHA-256 uses 32-bit words where as SHA-512 uses 64-bit words. This guarantees that if two users choose the same password, their hash value in the database will not be the same.
Hash is a one way function – it cannot be decrypted back. This makes it suitable for password validation, challenge hash authentication, anti-tamper, digital signatures.

Example: Hash values of empty string.

  • SHA224(“”)
    0x d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f
  • SHA256(“”)
    0x e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
  • SHA384(“”)
    0x 38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b
  • SHA512(“”)
    0x cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e
  • SHA512/224(“”)
    0x 6ed0dd02806fa89e25de060c19d3ac86cabb87d6a0ddd05c333b84f4
  • SHA512/256(“”)
    0x c672b8d1ef56ed28ab87c3622c5114069bdd3ad7b8f9737498d0c01ecef0967a
  • SHA224(“The quick brown fox jumps over the lazy dog”)
    0x 730e109bd7a8a32b1cb9d9a09aa2325d2430587ddbc0c38bad911525

Importance Of SHA-2 Hashing Algorithm

  • SHA-2 is used as cryptography algorithm for SSH, SSL, TLS, protocols.
  • Generating SHA-2 hash code for strings and texts will be useful for password encryption, validating the authenticity of email content, etc.

Now a days, SHA-2 is believe the most secure hashing algorithm. SHA-2 is a set of 6 hashing algorithm (SHA-256, SHA-512, SHA-224, SHA-384, SHA-512/224, and SHA-512/256).
1. SHA-512

SHA-512 is a 512 bit (64 bytes) hashing algorithm which can calculate hash code for an input up to 2128-1 bits. It undergoes 80 rounds off hashing. So, SHA-512 is stronger hashing than SHA-256. The calculated hash code will be a 124 digit hexadecimal number.

2. SHA-224

SHA-224 is the truncated version for SHA-256. The output hash code for this is 224 bit. This method can calculate hash code for an input up to 264-1 bits. It undergoes 64 rounds off hashing.

3. SHA-384

SHA-384 is the truncated version for SHA-512. The output hash code for this is 384 bit (i.e. 96 digit hexadecimal code). This method can calculate hash code for an input up to 2128-1 bits. It undergoes 80 rounds off hashing.

4. SHA-512/224

SHA-512/224 is the truncated version for SHA-512. The output hash code for this is 224 bit code. This method can calculate hash code for an input up to 2128-1 bits.

5. SHA-512/256

SHA-512/256 is also a truncated version for SHA-512. The output hash code for this is 256 bit code. This method can calculate hash code for an input up to 2128-1 bits. This method undergoes 80 rounds of hashing.

SHA-Comparison

Why SHA-512 is faster than SHA-256?

SHA-512 is faster than SHA-256 on 64-bit machines is that has 37.5% less rounds per byte (80 rounds operating on 128 byte blocks) compared to SHA-256 (64 rounds operating on 64 byte blocks), where the operations use 64-bit integer arithmetic.

Here, SHA-512 is identical in structure to SHA-256, but:

  • the message is broken into 1024-bit chunks,
  • the initial hash values and round constants are extended to 64 bits,
  • here are 80 rounds instead of 64,
  • the message schedule array w has 80 64-bit words instead of 64 32-bit words,
  • to extend the message schedule array w, the loop is from 16 to 79 instead of from 16 to 63,
  • the round constants are based on the first 80 primes 2..409,
  • the word size used for calculations is 64 bits long,
  • the appended length of the message (before per-processing), in bits, is a 128-bit big-ending integer.

Example based on Password using SHA-2 Hashing Algorithm  using Java:

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
 
public class SHAHashing {
  public static void main(String[] args) throws NoSuchAlgorithmException {
    String currentPassword = "userPassword";
    byte[] salt = getSalt();
    String SHAPassword =get_SHA_1_SecurePassword(currentPassword,salt);
    SHAPassword = get_SHA_256_SecurePassword(currentPassword, salt);
    SHAPassword = get_SHA_384_SecurePassword(currentPassword, salt);
    SHAPassword = get_SHA_512_SecurePassword(currentPassword, salt);
  }
  
  //Add salt
  private static byte[] getSalt() throws NoSuchAlgorithmException{
    SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
    byte[] salt = new byte[16];
    sr.nextBytes(salt);
    return salt;
  }
 
  private static String get_SHA_1_SecurePassword(String currentPassword, byte[] salt){
    String generatedPassword = null;
    try {
        MessageDigest md = MessageDigest.getInstance("SHA-1");
        md.update(salt);
        byte[] bytes = md.digest(currentPassword.getBytes());
        StringBuilder sb = new StringBuilder();
        for(int i=0; i< bytes.length ;i++){
        sb.append(Integer.toString((bytes[i] & 0xff) + 0x100, 16).substring(1));
     }
        generatedPassword = sb.toString();
    }catch (NoSuchAlgorithmException ex){
        ex.printStackTrace();
    }
    return generatedPassword;}
 
  private static String get_SHA_256_SecurePassword(String currentPassword, byte[] salt){
  //Use MessageDigest md = MessageDigest.getInstance("SHA-256");
   }
  private static String get_SHA_384_SecurePassword(String currentPassword, byte[] salt){
  //Use MessageDigest md = MessageDigest.getInstance("SHA-384");
   }
  private static String get_SHA_512_SecurePassword(String currentPassword, byte[] salt){
  //Use MessageDigest md = MessageDigest.getInstance("SHA-512");
   }
}

Keep watching for more in future!
References: