Encryption with PBKDF2

Reading Time: 4 minutes

Passwords can be the most valuable data to an attacker because stolen passwords can provide attackers the ability to bypass most of the security perimeters that exists in the system. Since lot of people use the same password in several other systems, one system compromise can affect the security of other systems too. This is where we can use encryption as a solution for theses security threats.

Hashing

Hashing is a successful way of keeping the passwords securely. With hashing, we can convert any size of data into a fixed set of characters. Main difference between hashing and encryption is that the hashing process cannot be reversed. Once we hash a data, we cannot retrieve its value again.

So how we can use hashing to store passwords securely?

First of all whenever a new user is registered, we should pass that user’s password through a hashing function before storing it in a database. During the user’s next login, we can simply pass the user entered password through the same hashing function and compare the output hash with the hashing value stored in the database to validate the user. Well after doing this we can ensure that even in a database breach the user passwords will be safe because the passwords are hashed and the attacker cannot extract the actual passwords from them.

Salting

If two users use the same password, there will be duplicate hashes in the password database. If an attacker sees this duplication, he will know that both users are using the same password. This gives the attacker the ability to compromise both accounts by compromising one. The solution is to append a system generated random value (salt) to the user entered password before hashing. This is termed as salting. Remember that we need to store the salt value along with the hash in order to validate the user upon his next login.

The original intent of salting was primarily to defeat pre-computed rainbow table attacks that could otherwise be used to greatly improve the efficiency of cracking the hashed password database. A greater benefit now is to slow down parallel operations that compare the hash of a password guess against many password hashes at once.

Important: We always need to use a SecureRandom to create good salts, and in Java, the SecureRandom class supports the “SHA1PRNG” pseudo random number generator algorithm, and we can take advantage of it.

How to generate Salt for Hash

Let’s see how salt should be generated.

private static byte[] getSalt() throws NoSuchAlgorithmException
{
    //Always use a SecureRandom generator
    SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
    //Create array for salt
    byte[] salt = new byte[16];
    //Get a random salt
    sr.nextBytes(salt);
    //return salt
    return salt;
}

SHA1PRNG algorithm is used as cryptographically strong pseudo-random number generator based on the SHA-1 message digest algorithm Note that if a seed is not provided, it will generate a seed from a true random number generator (TRNG).

Why PBKDF2?

Naturally  in programming developers search for the fastest algorithm. But intentionally to withstand brute force attacks, the hashing algorithms have been made slow. The super computing resources available today can attempt billions of hashes per second. If the algorithm is slow, the frequency of those attempts can be made slower. The trick is to make the algorithm slower such that it can withstand brute force attacks and still be fast enough not to harm the user experience.

Many applications had used MD5 as a hashing algorithm. But MD5 had several weaknesses.One of the problem was to generate same hash using different inputs. Due to these weaknesses the author himself declared that MD5 is unsuitable for hashing in 2005. Secure Hashing Algorithm (SHA) is another popular hashing algorithm. There are several versions such as SHA-0, SHA-1, SHA-2 and SHA-3. Even though SHA-0 and SHA-1 were unsuccessful, SHA-2 still has some strength left with it’s different variations of hash lengths. SHA family has also released SHA-3 improving its predecessors.

How to use PBkdf2 algorithm


Following is the example of usage of Pbkdf2 algorithm.

 public static void main(String[] args) throws NoSuchAlgorithmException, InvalidKeySpecException
    {
        String  originalPassword = "password";
        String generatedSecuredPasswordHash = generateStorngPasswordHash(originalPassword);
        System.out.println(generatedSecuredPasswordHash);
    }
    private static String hashPassword(String password) throws NoSuchAlgorithmException, InvalidKeySpecException
    {
        int iterations = 1000;
        int keyLength = 512;
        char[] chars = password.toCharArray();
        byte[] salt = getSalt();
         
        PBEKeySpec spec = new PBEKeySpec(chars, salt, iterations, keyLength);
        SecretKeyFactory skf = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
        byte[] hash = skf.generateSecret(spec).getEncoded();
        return iterations + ":" + toHex(salt) + ":" + toHex(hash);
    }
     
    private static byte[] getSalt() throws NoSuchAlgorithmException
    {
        SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
        byte[] salt = new byte[16];
        sr.nextBytes(salt);
        return salt;
    }
     
    private static String toHex(byte[] array) throws NoSuchAlgorithmException
    {
        BigInteger bi = new BigInteger(1, array);
        String hex = bi.toString(16);
        int paddingLength = (array.length * 2) - hex.length();
        if(paddingLength > 0)
        {
            return String.format("%0"  +paddingLength + "d", 0) + hex;
        }else{
            return hex;
        }
    }

This function has four input variables

password – the password that needs to be hashed. Before passing,it should be converted to char array

salt– salt value that should append to the password.

iterations– no. of iterations to be done. This value can manage speed of the algorithm.

keyLength– This is the required output length of the hashed function.

After executing this program with 100000 iterations in a laptop with a 2.6 GHz Core i-7 processor with 16GB RAM, the execution time takes approximately about 500ms and when it is increased up to 200000, the execution takes about 1000ms. Therefore in my opinion, the optimum number of iterations is somewhere between those two values. Anyway it is up to the developer to decide the optimum number of iterations according to the context.

Conclusion

After reading this blog you will have the idea how and why to use PBKDF2 algorithm for encryption of secure information and how is encryption very easy for our projects..

Reference

http://security.blogoverflow.com/2013/09/about-secure-password- hashing/

Written by 

Munander is a Software Consultant in Knoldus Software LLP. He has done b.tech from IMS Engineering college, Ghaziabad. He has decent knowledge of C,C++,Java,Angular and Lagom. He always tries to explore new technologies. His hobbies include playing cricket and adventure.

1 thought on “Encryption with PBKDF25 min read

Comments are closed.