In a previous post I explained why bCrypt is a good choice for hashing your passwords. In this post I will show were you can hash and check your passwords: in your handlers, in a service layer or in some entity model. When using cbsecurity I will show you why it fits best in your service layer or entity model.
But let’s start with some hashing and checking in a handler. Make sure bcrypt is installed by using commandbox and execute the command:
box install bcrypt
Let’s say you want to store your password in a db table. Bcrypt has two important methods for hashing and checking called
checkPassword() but you have to call them on a bcrypt instance, so you can inject bcrypt in a handler:
property name="bCrypt" inject="BCrypt@BCrypt";
or getting your instance directly by calling
getInstance("BCrypt@BCrypt"). But you don’t have to do this, by installing the module some mixin helpers are created so you can just call
bCryptCheck(). These handy functions will be available in all handlers, views, layouts or even interceptors. So let’s say we want to save a user in some handler it will look like this:
I have to admit. This is not the most useful post I ever wrote, but today I discovered something funny but interesting when I tried to fix some small bug. I was working with the bcrypt module. If you don’t know what this module is doing: it is a very secure way for hashing passwords, and since checking the validity of your password is relatively slow it is quite useful to prevent password cracking. Before diving into bugfixing let’s see what bcrypt is doing. It is a coldbox module and only has a few relevant functions:
hashPassword(password, [ workfactor], [salt]) which generates a password hash based on a salt and a workfactor. If you don’t supply a workFactor or salt, the coldbox module will generate a salt with a default workfactor of 12. The higher the workfactor, the longer it takes to check for a valid password. (on my system a workfactor means it takes 200 milliseconds to check for a valid password.
checkPassword( candidate, bCryptHash) will check a password candidate agains a (stored) bcryptHash.
generateSalt( workFactor ) will generate a salt, based on a workFactor. Increasing a workfactor by 1 will mean it takes double the time to check your bCryptHash. This way you can prevent password attacks, because generating and checking is relatively slow.
We all know. We should never ever store a plaintext password in a database. If a hacker gains access to your data you will be in serious trouble. There are many ways to protect your data, but at least you should make sure your passwords are not readable. In the past we did this by some simple hashing, but modern computers are so fast it is easy to do some password cracking. In time it even gets easier because processors are becoming faster and faster. Another disadvantage: simple hashing will reveal some records with the same passwords. These are often the easiest to guess or crack by brute force. So we need something better.
Coldbox has a nice little module called bcrypt, which is just a wrapper to the jBcrypt java library which is a Java™ implementation of OpenBSD’s Blowfish password hashing code. Wikipedia has a nice description of the bcrypt password hashing algoritme. Bcrypt hash some strong points:
- generating a hash for the same string will always return different results
- comparing a password candidate with the stored hash is relatively slow, which makes brute force attacks harder.
- the hash can be generated with different workfactors. The higher the workfactor, the more time it takes to compare your hash with a password candidate. By increasing the workfactor in time you can account for faster processors, so brute-force attacks remain unattractive.