Book Image

Instant Java Password and Authentication Security

By : Fernando Mayoral
Book Image

Instant Java Password and Authentication Security

By: Fernando Mayoral

Overview of this book

Password security is a critical matter when it comes to protecting the interests of application users and their data for a satisfactory user experience. With the advancement in technology, now more than ever, application developers need to be able to implement reliable mechanisms to prevent passwords from being stolen. Java Password and Authentication Security provides a practical approach to implement these reliable mechanisms with the possibility to make password authentication stronger as technology makes it easier to break them. Java Password and Authentication Security is a practical, hands-on guide covering a number of clear, step-by-step exercises and code examples that will help you to implement strong password authentication solutions for your project in no time. This book starts off with the most basic and well known hashing technique to quickly get an application developer started with implementing a standard password protection mechanism. Furthermore, it covers the stronger SHA (standard hashing algorithm) family in detail and brings up a technique to improve the hash security with a technique called “salting”. You will also learn how to use these hashes, and more importantly, when to use each technique. You will learn that not every hash algorithm is good in every situation, and how to deal with password recovery, password authentication, and timing attacks.
Table of Contents (7 chapters)

Adding salt to a hash (Intermediate)


This recipe teaches how to properly salt hashes to make them even stronger. As you may have guessed, this technique involves adding something to our hashes to make them harder to break.

How to do it...

To sign up or change a password, follow the given steps:

  1. Generate a random salt value.

  2. Create a MessageDigester with an algorithm you prefer.

  3. Add the salt to the MessageDigester .

  4. Digest the password with the MessageDigester.

  5. Get the hash from the digest.

  6. Save the generated salt and the hashed password. In case of sign up, we need to save the username.

To generate a random salt value, consider the code shown in the following screenshot:

We always need to use a SecureRandom class to create good salts. In Java, the SecureRandom class supports the "SHA1PRNG" pseudo random number generator algorithm, and we can take advantage of it. Note that we are returning the salt as a byte array, that's because the MessageDigest requires byte arrays. Also, you may have noticed that we created a salt of the size 16 bytes. This is important in order to ensure that our salt is strong enough. Never create a salt shorter than a 16-byte length. This means 128-bit strength (16 x 8 = 128) for the salt.

Now that we know how to create the salt, consider the code for creating a hashed password using the salt as shown in the following screenshot:

Notice that this method receives the salt method as a parameter and updates the MessageDigest byte buffer with the salt value. After that, it digests the password method as a byte array. Internally, it concatenates the salt with the password before digesting.

We can already generate a salt and use it to create a stronger hash, but we will create salts only when the user signs up or when he changes his password. On the other hand, when he authenticates, we need to validate his password. In order to do this, we need to create the same hash, which means that we need to store the salt somewhere.

The following screenshot is just an example of a basic user creation that uses the preceding methods:

As you can see, there is a User class. This is just a sample, the User class has a Username, a Password, and a Salt attribute. Also, you may have noticed a new toHex method, which converts a byte array to a hexadecimal string. We will need another fromHex method later, which converts a hexadecimal string to a byte array. The following screenshot is the implementation of these methods:

The toHex and fromHex methods are implemented in many different libraries and are a standard algorithm. In this example, we have the choice to implement them ourselves to avoid loading any dependencies.

Now that we saw a demonstration of how to create a hash with a salt and saving the generated password and salt we need to check how to validate the user identity when the user logs in.

Consider the following method to validate a user as shown in the screenshot:

As you can see, we retrieve the user class from the database and get the original salt to create the hash. After that, we compare the hashes: if they are equal, the password is valid! Note that we use the fromHex method here to get the byte array value of hexadecimal strings.

Remember that this is a sample code to show how to use the hash and the salt.

How it works...

When a password is simply hashed, we will eventually realize that identical passwords generate identical hashes—this is not good! Also, plain hashes can be compared with precomputed hashes (also known as rainbow tables).

In order to avoid, or at least make it harder to break our passwords, we can add random data to the original password. This will make every hash different, even if the passwords are the same.

This random data we add is called salt. A salt is a random value of fixed length. The salt generated for a given password must be saved in order to generate the stored hash again.

Now, in the code shown in the preceding screenshot, we are storing the plain salt. This is ok, but it could be better. Consider encrypting the salt with a two-way algorithm in order to have additional protection. Storing it in a different database could also help in making it harder to get. We are not doing that here, but these are very good options to increase security. However, the salt should be pretty secure with a strong hash (SHA-256 or stronger) and a good salt (16 bytes or more). Let's think about this like a hacker: we managed to get the database and the application's source code, but on checking the source code we notice that every single password has a random salt. This means that we can't use rainbow tables. Also, dictionary/brute-force attacks would be really expensive and we would need to get the passwords as soon as possible because someone might notice our intrusion and take measures to prevent such incidents—it's a nightmare!

There's more...

When it comes to salts, there is much misinformation. Salt is a must-do for secure systems, as it is fairly easy to break a weak password even if it's hashed with a secure algorithm. When we add salt to the equation, breaking the password gets significantly harder.

Never re-use a salt, it's pointless. It makes your hashes weak against dictionary, brute-force, and rainbow table attacks. So, salts are not reusable.

Short salts are not an option, salts should be at least 16 bytes length. If we have, let's say, a three character salt, there are only 857.375 (95 x 95 x 95 = 857.375) possible salts. Consider that a lookup table with the most common passwords contains around 1024 bytes. This means that the rainbow tables for the possible salts, and the most common passwords would be around 837 GB approximately. Nowadays, that's not a lot.

Crazy hashing and salting

Some people suggest using double hashing techniques or mixing different hashing algorithms and then creating a new hash with the digests. Although this may work, it's not a good option and I do not recommend it. There are other standards and well-tested techniques to make our hashes even stronger, so avoid trying to create your own technique.