About Bozhidar Bozhanov

Senior Java developer, one of the top stackoverflow users, fluent with Java and Java technology stacks - Spring, JPA, JavaEE, as well as Android, Scala and any framework you throw at him. creator of Computoser - an algorithmic music composer. Worked on telecom projects, e-government and large-scale online recruitment and navigation platforms.

Bcrypt, Salt. It’s The Bare Minimum.

The other day I read this Arstechnica article and realized how tragic the situation is. And it is not this bad because of the evil hackers. It’s bad because few people know how to handle one very common thing: authentication (signup and login). But it seems even cool companies like LinkedIn and Yahoo do it wrong (tons of passwords have leaked recently)

Most of the problems described in the article is solved with bcrypt. And using salt is a must. Other options are also acceptable – PBKDF2 and probably SHA-512. Note that bcrypt is not a hash function, it’s an algorithm that is specifically designed for password storage. It has its own salt generation built-in. Here are two stack exchange questions on the topic: this and this. Jeff Atwood has also written on the topic some time ago.

What is salt? It’s a random string (series of bits, to be precise, but for the purpose of password storage, let’s view it as string) that is appended to each password before it is hashed. So “mypassword” may become “543abc7d9fab773fb2a0mypassword”. You then add the salt every time you need to check if the password is correct (i.e. salt+password should generate the same hash that is stored in the database). How does this help? First, rainbow tables (tables of precomputed hashes for character combinations) can’t be used. Rainbow tables are generated for shorter passwords, and a big salt makes the password huge. Bruteforce is still possible, as the attacker knows your salt, so he can just bruteforce salt+(set of attempted passwords). Bcrypt, however, addresses bruteforce, because it is intentionally “slow”.

So, use salt. Prefer bcrypt. And that’s not if you have to be super-secure – that’s the absolute minimum for every website out there that stores passwords. And don’t say “my site is just a forum, what can happen if someone gets the passwords”. Users tend to reuse passwords, so their password for your stupid site may also be their email of facebook password. So take this seriously, whatever your website is, because you are risking the security of your users outside your premises. If you think it’s hard to use bcrypt, then don’t use passwords at all. Use “Login with facebook/twitter”, OpenID (that is actually harder than using bcrypt) or another form of externalized authentication.

Having used the word “minimum” a couple of times, I’ll proceed with a short list of things to consider in terms of web security that should be done in addition to the minimum requirement of using salt. If you are handling money, or some other very important staff, you can’t afford to stay on the bare minimum:

use https everywhere. Sending unsecure session cookies can be sniffed and the attacker can “steal” the user’s session.

one-time tokens – sends short-lived tokens (codes) via SMS, or login links – via email, that are used to authentication. That way you even don’t need passwords (you move the authentication complexity to the mobile network / the email provider)

encourage use of passphrases, rather than passwords – short passwords are easier to bruteforce, but long passwords are hard to remember. That’s why you could encourage your users to use a passphrase, like “dust in the wind” or “who let the dogs out”, which are easy to remember, but hard to attack. (My signup page has an example of a subtle encouragement)

require additional verification for highly-sensitive actions, and don’t allow changing emails if the login was automatic (performed with a long-lived “remember-me” cookie)

lock accounts after failed consecutive logins – “bruteforce” should only be usable if the attacker gets hold of your database. It should not happen through your interface.

use certificates for authentication – public-key cryptography can be used to establish mutual trust between the user and the server – the user knows the server is the right one, and the server knows the user is not a random person that somehow obtained the password.

use hardware tokens – using digital signatures are the same as the above option, but they store the certificates on hardware devices and cannot be extracted from there. So only the owner of the physical device can authenticate

Web security is a complex field. Hello world examples must not be followed for real-world systems. Consider all implications for your users outside your system. Bottom-line: use bcrypt.

and many more ....

2 comments

‘you could encourage your users to use a passphrase, like “dust in the wind” or “who let the dogs out”, which are easy to remember, but hard to attack.’ You misunderstood xkcd. Passphrases are NOT inherently stronger. The reason xkcd’s passphrase was strong was because of the entropy he used to generate the passphrase. “Dust in the Wind” is not randomly derived and is a pop-culture reference to boot. Highly patternized passwords can be broken using Markov Chains. Diceware changes the pieces of information from characters to words and vastly increases the entropy per piece (~2x). Using a 8192-word wordlist with a CSPRNG to generate a six-word passphrase is approximately equivalent to a 12-character alphanumeric-plus-symbols password. Password strength is based on the amount entropy not length nor complexity.

Career Opportunities

Newsletter

Join them now to gain exclusive access to the latest news in the Java world, as well as insights about Android, Scala, Groovy and other related technologies.

Email address:

Receive Java & Developer job alerts in your Area from our partners over at ZipRecruiter

Leave this field empty if you're human:

Join Us

With 1,240,600 monthly unique visitors and over 500 authors we are placed among the top Java related sites around. Constantly being on the lookout for partners; we encourage you to join us. So If you have a blog with unique and interesting content then you should check out our JCG partners program. You can also be a guest writer for Java Code Geeks and hone your writing skills!

Disclaimer

All trademarks and registered trademarks appearing on Java Code Geeks are the property of their respective owners. Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries. Examples Java Code Geeks is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.