14

I'm learning about pass hashing at the moment in the context of nodejs and I was wondering what would you recommend as the salt level. The default level is 10 and I was wondering if this is good enough for basic applications with less than 10 users.

2 Answers 2

16

To answer your question, I created a simple Python test script:

#!/usr/bin/env python3 import bcrypt import time passwd = b's$cret12' for i in range(4,17): print(f'Rounds:{i}') start = time.time() salt = bcrypt.gensalt(rounds=i) hashed = bcrypt.hashpw(passwd, salt) end = time.time() print(f'Rounds:{i} | Time: {end - start:.4f} s') 

And got the following result on Intel(R) Xeon(R) CPU E5-2620 v4 @ 2.10GHz:

Rounds:4 | Time: 0.0016 s Rounds:5 | Time: 0.0029 s Rounds:6 | Time: 0.0060 s Rounds:7 | Time: 0.0115 s Rounds:8 | Time: 0.0232 s Rounds:9 | Time: 0.0459 s Rounds:10 | Time: 0.0907 s /* Good enough */ Rounds:11 | Time: 0.1834 s /* Worth considering */ Rounds:12 | Time: 0.3563 s /* >250ms as discussed in comments */ Rounds:13 | Time: 0.7215 s Rounds:14 | Time: 1.4437 s /* for critical systems and superuser passwords */ Rounds:15 | Time: 2.9140 s Rounds:16 | Time: 5.8405 s 

Hence, you may consider these numbers to understand how long it takes to check 1 password against hash tables of common words.

Today, I would consider something around 0.1 second per password is good enough (if you don't allow users to use simple passwords like '123456'). Hence, consider 10 or 11 rounds.

  • Remember, it doesn't PROTECT your users but just buys them time to change their passwords safely if your password database is compromised.

Update for Apple M3 MAX (40 cores):

 . . . Rounds:10 | Time: 0.0848 s Rounds:11 | Time: 0.1691 s Rounds:12 | Time: 0.3380 s Rounds:13 | Time: 0.6782 s Rounds:14 | Time: 1.3506 s . . . 

Hence, consider 11 rounds as the default value for general users.

Sign up to request clarification or add additional context in comments.

2 Comments

The "Good enough", and even "Worth to consider" times above might still be considered too fast. From what I've read, a cost of 250ms for a hash is around the more normal target (obviously this is a general norm, but everyone should consider their own use case carefully). Ian Boyd's answer in this stackoverflow.com/questions/4443476/optimal-bcrypt-work-factor gives a bit more background to the 250ms time.
Thank you for the link! Appreciate it. Updated the original post. With that, I would say that it depends on a purpose. I still thinking that ~0.2s is enough (it is not far away from the proposed 250ms in the paper). But yes, it is worth aiming even to 1s in critical systems.
2

It doesn't matter how many users you have. One could argue that if you only have 10 users then you have more resources per user to keep them secure.

A good answer to the question of how many rounds are ok is to answer a question - how many rounds can you afford without degrading performance?

Sometimes the defaults are fine but sometimes you can do better than that. You really have to test it yourself and measure the impact.

Comments