Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Save more on your purchases! discount-offer-chevron-icon
Savings automatically calculated. No voucher code required.
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Free Learning
Arrow right icon
Arrow up icon
GO TO TOP
Instant Java Password and Authentication Security

You're reading from   Instant Java Password and Authentication Security A practical, hands-on guide to securing Java application passwords with hashing techniques

Arrow left icon
Product type Paperback
Published in Nov 2013
Publisher Packt
ISBN-13 9781849697767
Length 38 pages
Edition 1st Edition
Languages
Arrow right icon
Author (1):
Arrow left icon
Fernando Mayoral Fernando Mayoral
Author Profile Icon Fernando Mayoral
Fernando Mayoral
Arrow right icon
View More author details
Toc

Table of Contents (7) Chapters Close

Instant Java Password and Authentication Security
Credits
About the Author
About the Reviewers
www.PacktPub.com
Preface
1. Instant Java Password and Authentication Security

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.

lock icon The rest of the chapter is locked
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at $19.99/month. Cancel anytime
Banner background image