
Bcrypt
To have secure logins, we need a way to store users's passwords.
Because hackers have been known to penetrate into secure
servers, we need extra layers of defense. In particular, we will not
store the plaintext password, but rather a one-way hash of the
password.
Hashed Passwords¶
How does that work? There are two phases to the process: creating an account and verifying a password when someone logs in.
Imagine that Neville Longbottom is creating an account and he wants to
use dilligrout
as his password.
Account Creation
Neville fills out the form, the server receives the username
(nlongbottom
) and password (dilligrout
). It computes a hash of
the password, and stores the username and hash:
username | passwd |
---|---|
nlongbottom | 591747ca7ce5608a92d17236d3b1d0d7a80968f764bc13288e4471d0bd30060b |
The system then discards the plaintext password, not storing it anywhere.
Login
Later, when Neville logs in, he provides the same username and
password (he carefully wrote the password down so he wouldn't forget
it!), the system again computes the hash of dilligrout
and gets
591..60b
. That matches the stored hash, and Neville is logged in.
Hackers
If Malfoy hacks into the server and gets Neville's hashed password, he
can't reverse the computation to get "dilligrout" and so he can't use
the hashed password to login. His only hope is to run the one-way hash
forward on many, many possible passwords, hoping that one of them
will hash to the 591...60b
value. If he hits on "dilligrout", it
will, of course, match, and he'll know Neville's password.
Salt¶
The scheme above has two weaknesses. First, a user can choose a stupid password, one the attacker can easily guess. Secondly, two or more users might choose the same password, and the attacker needs to only guess one to get them all. The notion of adding salt to the password addresses these weaknesses.
First, let's understand the weaknesses. Suppose Goyle chooses '123' as his password, because he has trouble remembering a better password. If the attacker tries all strings less than 5 characters in length (there are fewer than a billion strings of lowercase letters and digits of length 5 or less) the attacker will certainly succeed. Even better, the attacker can pre-compute the hash values of common passwords like '123' and just compare to the stored hashes.
Furthermore, suppose Crabbe also uses that password. His hashed password is exactly the same as Goyle's, so when the attacker hashes '123' and searches the password database, they get two matches, so both accounts are compromised.
Instead, we create a random string, called salt
at the time
that each person creates their account, and store that salt along with
the encrypted password. The password algorithm combines the salt and
the password (essentially creating a longer password), hashes the
longer string, and proceeds as usual.
username | salt | passwd |
---|---|---|
nlongbottom | xocivu | cdde1bed702518ef735ac8530915dff3689a4594687c9993254eb785ad6d91d6 |
crabbe | Z98xbs | 174c4a5799b09c0adae18bfe566c23684e68345fc4feca8b0b98bd1a1b5ce1c5 |
goyle | v5bnws | 0478d2c697c0dcdc276e44514069f44a369defee06bcf4a2a19c9e3020cc2e43 |
Thanks to the salt, now the hacker
- can't pre-compute the hashes, since they involve a custom salt, and
- can't match multiple users because even if they have the same password, they will have unique salt strings.
Thus, salt is an important ingredient in password security.
Reading¶
Please read the following references:
- Dustin Boswell: How to handle Passwords. I like this presentation a lot. Unfortunately, that site has been taken down, but I found a copy archived by the Internet Archive (the WayBack machine) in April 2019: Dustin Boswell on How to Handle Passwords
- Coda Hale: How to Safely Store a Password. You know where this person stands!
- bcrypt python module