I'm developing a social website as a side-project and seeing if it actually goes anywhere. I'm using bcrypt right now to store passwords and unfortunately I'm only able to get my webserver to do a work factor of 10 in 0.1 seconds. This seems really small compared to what was recommended here, not to mention a much higher amount of time than the 8 milliseconds recommended. I'm using shared web hosting at the moment and would love to move to a dedicated server but cannot afford to do so.

Is there much value in using bcrypt with a low work factor like 10 until a later point when I'm able to cover the cost of a dedicated server, or is there an alternative way I could go about securely storing passwords? Am I looking at this problem wrong?



It shall first be noted that password hashing is a second line of defence. You store in your server's database some value which allows password verification; your first duty is not to allow outsiders to grab a copy of that value. So first apply all security updates for your software; develop code with great care and appropriate methodology (e.g. when accessing the database, use prepared statements); and mind your operational procedures (don't leave your backups unattended, destroy hard disks upon decommissioning, and so on).

Using slow hashing is meant to make the task harder for the attacker in case he still succeeds at getting a glimpse at your database. Unfortunately, this makes password processing harder for you too, so that's a trade-off. With bcrypt, a work factor of n means that there are 2n internal iterations; a work factor of "10" means that you have made dictionary attacks about a thousand times less efficient (since 210 = 1024). Depending on your outlook, this may be great or insufficient, but this is still non-negligible.

To improve things, there are various methods that you may want to consider:

  • Use a "pepper", i.e. an extra server-wide secret key; this turns the password hashing into a MAC. Basically, when you "hash the password" (upon registration, and upon verification), you compute HMAC/SHA-256 over the password, encode the 32-byte output in Base64 (so that it becomes a nice string of printable characters), then use that string as input to bcrypt.

    That process improves security under the assumption that the attacker may get a copy of the hashed passwords but not of the whole server (e.g. the attacker could make some SQL injection but not read the server configuration files). In particular, don't store the key in the database itself.

  • Help users choose stronger passwords. Mind the words: I said "help", not "force". In particular, do NOT try to enforce "password complexity rules" like requiring a mix of uppercase, lowercase, and sumerian ideograms. Such rules, in practice, do not make passwords stronger; they just make users angrier. Instead, a good thing would be to offer a generator tool that produces high-entropy but easy-to-memorize passwords (see this question for guidance). It is important that the tool is optional because you want users to freely cooperate with your security strategy; if you make anything mandatory then they will rebel and things will be worse.

  • Offload the problem into the hands of somebody else. This means authenticating users through something like OpenID; the OpenID provider is an external system that handles the password verification for you.

    A notable example is StackExchange itself: although they can handle the password registration and verification themselves, they also allow you to register using your existing Google or Facebook account, or just any OpenID provider.

  • Buy a bigger, more powerful server.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy