Your daily dose of Java and related technologies.
News, Releases, Reviews, Tutorials, Articles, Events, Contests, Comments, Code and much more.
This java weblog is maintained by Xyling Technologies, making life simpler.

Monday, May 07, 2007

Encrypting your password before storing in to the database.

Have you ever felt the need to encrypt those plain text passwords you store in the database for your application authentication?
Would you like to encrypt the plain text in such a way that it can only be interpreted by your application and does not make sense for a naked eye?
Here is a simple code to encrypt a plain text.

public synchronized String encrypt(String plaintext) throws SystemUnavailableException
{
MessageDigest md = null;
try
{
md = MessageDigest.getInstance("SHA"); //step 2
}
catch(NoSuchAlgorithmException e)
{
throw new SystemUnavailableException(e.getMessage());
}
try
{
md.update(plaintext.getBytes("UTF-8")); //step 3
}
catch(UnsupportedEncodingException e)
{
throw new SystemUnavailableException(e.getMessage());
}

byte raw[] = md.digest(); //step 4
String hash = (new BASE64Encoder()).encode(raw); //step 5
return hash; //step 6
}

While comparing, ecrypting the comparing plain text using the same code.
For a detailed analysis, point to the title of this post.
Thanks to James Shvarts.

[Resource-Type: Source Code; Category: J2EE/cryptography; XRating: 4]

4 Comments:

Anonymous Robin said...

This method isn't very good, as there is no salting involved. Ideally you'd do something like this, but include a salt value. A salt value is a random value that is pre- or appended to the password before hashing, and then the salt is stored along with the hash in the database. A simple SHA hash can be broken using rainbow tables if the attacker gets your database. For every bit of salt you include, you double the size of the tables that would need to be generated to attack it. It also means that should one password be cracked, that information isn't valid for any other hash, so slows down the brute forcing.

1:14 AM

 
Blogger Xyling Technologies said...

Good point Robin. I agree with you. This code more or less prevents the code from a naked eye.

Would you like to share some code or link with us to make it saltier?

Thanks for the comment.

10:33 AM

 
Anonymous Robin said...

I don't have any code around that does this at the moment (although I do need to write some up for my own use, maybe later today if I get time), but the pseudo-java using the bits you have above would be something like:

salt = /n/-byte string, randomly generated
// Prepend the salt
md.update(salt.getBytes("UTF-8"));
// append the password
md.update(plaintext.getBytes("UTF-8"));

// Create the storable hash with salt
String hash = salt + "$" + (new BASE64Encoder()).encode(raw);

This means that your hash looks like:
salt$sha-hash-of-pwd. When testing, you take the salt off the start, prepend that to the password the user supplied, and ensure that the resulting hash matches. Now, every time the same password is hashed, it will result in a completely different hash, making it harder on an attacker. As for what size to use for the salt, I don't think it really matters if you have too much. Each bit makes it twice as hard for the attacker, and costs you very little. Original UNIX passwords used 12 bits, but I think things are typically larger now. Probably would be safe to throw 64 or even 128 bits at it.

Time permitting, I'll write one soon for my own use and share it.

3:56 AM

 
Anonymous Justen Stepka said...

You may want to check out the Acegi PasswordEncoder object, which can do just about any implementation you need in term of encryption... it also support salting and provides a validation method.

6:38 AM

 

Post a Comment

<< Home