First of all, you should never store passwords. Then why the heck am I writing this post? Okay, Let me rephrase the first sentence – You should never store passwords as plain text anywhere in your application. of course, for the obvious reasons. If you store passwords as plain text, in database or in a log file, then even Rajinikanth couldn’t save your application getting hacked. (Edit: btw, Rajinikanth is the Chuck Norris of India, if you are not aware of him)
Then what’s the right way to deal with the asterisks? You could use encryption. But if there’s a way to encrypt it, then there should be a way to decrypt it. So, encryption is also vulnerable to hacker’s attack.
Isn’t there a better solution to this? It’s there and its called as Password Hashing.
How password hashing works?
In hashing, you take a input string (in our case, a password), add a salt to the string, generate the hash value (using SHA-1 algorithm for example), and store the hash value in DB. For matching passwords while login, you do the same hashing process again and match the hash value instead of matching plain passwords and authenticate users.
Hashing is different from encryption. Because, encryption is two way, means that you can always decrypt the encrypted text to get the original text. But Hashing is one way, you can never get the original text from the hash value. Thus it gives more security than encryption.
To generate hash, you can make use of any hashing algorithms out there – MD5, SHA-1, etc. Before generating a hash, adding a salt to the password will give added security. Salt is nothing but a simple text that is known only to you/your application. It can be “zebra” or “I’mGod” or anything you wish.
Below, I’m giving a Java example of how to do password hashing in an login module.
Password hashing example in Java
This is simple example containing two methods – signup() and login(). As their names suggest, signup would store username and password in DB and login would check the credentials entered by user against the DB. Let’s dive into the code.
package com.sandbox;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.Map;
public class PasswordHashingDemo {
Map<String, String> DB = new HashMap<String, String>();
public static final String SALT = "my-salt-text";
public static void main(String args[]) {
PasswordHashingDemo demo = new PasswordHashingDemo();
demo.signup("john", "dummy123");
// login should succeed.
if (demo.login("john", "dummy123"))
System.out.println("user login successfull.");
// login should fail because of wrong password.
if (demo.login("john", "blahblah"))
System.out.println("User login successfull.");
else
System.out.println("user login failed.");
}
public void signup(String username, String password) {
String saltedPassword = SALT + password;
String hashedPassword = generateHash(saltedPassword);
DB.put(username, hashedPassword);
}
public Boolean login(String username, String password) {
Boolean isAuthenticated = false;
// remember to use the same SALT value use used while storing password
// for the first time.
String saltedPassword = SALT + password;
String hashedPassword = generateHash(saltedPassword);
String storedPasswordHash = DB.get(username);
if(hashedPassword.equals(storedPasswordHash)){
isAuthenticated = true;
}else{
isAuthenticated = false;
}
return isAuthenticated;
}
public static String generateHash(String input) {
StringBuilder hash = new StringBuilder();
try {
MessageDigest sha = MessageDigest.getInstance("SHA-1");
byte[] hashedBytes = sha.digest(input.getBytes());
char[] digits = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'a', 'b', 'c', 'd', 'e', 'f' };
for (int idx = 0; idx < hashedBytes.length; ++idx) {
byte b = hashedBytes[idx];
hash.append(digits[(b & 0xf0) >> 4]);
hash.append(digits[b & 0x0f]);
}
} catch (NoSuchAlgorithmException e) {
// handle error here.
}
return hash.toString();
}
}
So, that’s it. I guess the above code is self explanatory. Do let me know in case you have any doubts.


{ 29 comments… read them below or add one }
I never knew hashing existed.
I thought encryption was the only thing people use. Mm.. need to learn more. I like this one way hashing over two way encryption. Thanks for the info.
You are welcome.
May God saves us and our apps from asterisks.
I bet he will.
Hi Veera, this is an informative article indeed.
Just to add there are still many types of security implementation possible and you have listed many of them & its a design decision to see which one needs to be used.. By any chance do u have plans to post on them?
yes Kiran. There are lots of other security mechanism available and its definitely based application’s architecture to choose one. The technique I explained above can been seen in web application’s often, because container based authentication is little difficult in web applications.
For Java enterprise projects, either JAAS or container based authentication can be used.
As of now, I don’t have any plans to list out all the security method. but plans are made to be changed.
Hashing is vulnerable to brute force attack. So password has to be chosen wisely.
//Hashing is vulnerable to brute force attack//
by adding a salt at the server side, we are minimizing the risk of brute force attack. Even the rainbow table attack will take some time to break the salted and hashed password.
I agree that the password has to be complex and that’s a basic requirement irrespective of the encryption/hashing method used.
“But Hashing is one way, you can never get the original text from the hash value. Thus it gives more security than encryption.”
If password is stored as hash value in database, How do we get the original text in case of “Forgot Password ?”.
that is a very good question.
in such scenarios of forgetting the passwords, the user should be allowed to reset it to a new password, instead of the application sending the user the old password.
and the link to reset the password should be sent to the user’s email address, to avoid people resetting other’s passwords.
You should use a random salt for each password, not a single salt for the whole system. Using a single salt makes a rainbow attack much easier.
//Using a single salt makes a rainbow attack much easier//
If the salt is kept secret, it’ll make the hacker’s life difficult. IMO, a single salt text would be sufficient. But again, it’s a design decision and has to be taken considering the criticality of the application.
//You should use a random salt for each password//
in that case, the salt text (for each user) also has to be stored in DB.
Or you could just include the username (assuming it’s unique) or the primary key of the user in the hash input.
and you should never let the outer world know that you are using user name as salt, because user name is going to be public anyway.
if you are hacked, they are going to find your salt anyway. You should indeed use a salt per password, so in case they find your salt, they wont be able to generate an entire rainbow table and recover all available passwords.
In case of security you should always calculate what the data you are protecting is worth. If they hack your password, how much are they going to gain. If it costs them more to crack the hash than it gains them then you have good security. So if it costs 0.05 cent to bruteforce one hashing cycle and the data is worth 0.1 cent, hash it multiple time, adding the salt each time.
Either way, you should be using jasypt or some other library for storing passwords (unless of course you are stuck to e.g. container based authentication in J2EE where you can only choose the default Java Providers)
Nice example. I would add that sha1 is a superior choice to MD5 (less chance of collision, tougher to compromise, etc.)
yes. agree on that. MD5 has been found defective at many occasions.
That’s not the point of the salt. Using the same salt actually makes the hacker’s life easier. Using a single salt will cause the same password used by different users to hash to the same value. Using a randomized salt per user causes each hash to be different. It doesn’t matter if the hacker knows the salt. He/she would have to generate a separate rainbow table for each password.
then as Wouter said above, the user name can be used as the salt to generate hash for each password.
good one Veera… but still there is something called jBCrypt password scheme… this is quite simple and safe.. if possible have a look there as well…
Is there a way to hash the information from the browser itself?
Like in a browser based webapplication, lets say I have a signup page that will submit through SSL. But on top, I also want to hash the data (password, ssn etc) before the page gets submitted from the browser. How do I accomplish this? Do I need to look into a webapplication firewall? I just want some direction in this regard.
Thanks
Amit
This is simple to use BASE64Encoder ( or you can use apache BASE64Encoder)
import sun.misc.BASE64Encoder;
public static String generateHash(String input) {
String hash = “”;
try {
MessageDigest sha = MessageDigest.getInstance(“SHA-1″);
byte[] hashedBytes = sha.digest(input.getBytes());
hash= (new BASE64Encoder()).encode(hashedBytes );
} catch (NoSuchAlgorithmException e) {
// handle error here.
}
return hash;
}
Hi Veera. I have this question popup in my head long long ago. Where should we store the hashed password for an java application? I mean.. Let say we have a application software which store the hashed password in a local file, the hacker can just install again the software somewhere else and get the default password file to replace with the existing 1, thus can login use the default password.. So is there any other method to protect from this action??
Hi Derrick,
Usually the username/password combination is stored in a database system.
Storing the passwords in flat (local) files is not a good idea as for controlling access to a file is not easy, need some third party tools and not reliable.
But if the data is stored in database, the DB will manage the access control and it will block the hacker from accessing the sensitive data.
Okay.. but the database you mean.. is it created and used only by the java-application itself, or the user of the pc must install a database seperately before using our software? (i.e. the user is using a new pc without any software installed)
I assume you are talking about the Java desktop applications.. in that case, it is the application’s responsibility to install the database.
You can try using embedded database systems, such as Java DB. Here’s an article: Using Java DB in Desktop Applications.
Thanks Veera.. That is just what i needed!
I am new to security terminologies kind of rainbow table.I am getting most of what you guys are discussing here. I have some questions here.
Here we are talking about four data elements. user name, user’s password, user’s salt and server salt.
Now Application have to use CORRECT server side salt string authentication every time. If hacker is trying to hack user’s password with different combination of user’s password & user’s salt. if he is able to break it he will know that user’s password & salt string. He will not be able to know server side salt.
If Application has to use correct salt every time then what is the use of server salt?
All we are trying to add here is by adding salt more layer of defence. All defence layers are good only if user is remembering all these layer’s in his mind. It will be useless if server has to remember it AND use it to validate password.
What’s your view on this?