Welcome. Today, we're going to talk about
slowing down password brute force attacks.
We're going to review the previous videos
example of storing password-related information.
Then we're going to talk about salting and hashing.
Then talk briefly about slowing down
the brute force calculations with PBKDF2.
After this lesson, you'll be able to
discuss and explain salting and hashing,
and discuss ways to slow down brute force calculations.
Let me explain. From our previous video,
we talked about an example
and it is here for your convenience.
Remember how we said that one way someone could implement
this web application authentication mechanism is to use
a cryptographic hash function to
take the password that's given,
and then take the calculation of the hash function and
store the hash output as a key,
and the value being the username.
In this way, the plain text password
is not actually stored.
Remember how we said that if
an attacker can steal this database,
they can do one of two things.
They can either use a wordlist and perform
the same one-way hash calculation to check if they
have a matching plain text password in the wordlist.
If they are able to calculate
the same hash that's contained in
the database given some word in the wordlist,
then they know that the word in
the wordlist is a correct password.
Another thing that an attacker can do is to
perform brute force calculations,
basically for a certain length of a password,
trying every single combination of characters to perform
the hash and compare
the hash result to a hash in the database.
Further, based on the example that we just talked about,
if you just use that hash function for the password,
then if you have two users that
have the same exact password,
then that means that they would
have the same hash output.
That same hash output is stored in the database,
then the attacker has a higher chance of
knowing what the actual password is.
The answer to presenting this is to add a salt.
What a salt is,
is a fixed length randomly generated
string that is used to then
concatenate with the plain text password
before performing the hash calculation.
Now, because performing the hash on
the same string always produces the same hash output,
if two or more users have the same password,
then they would have the same hash.
So because of that problem in order
to randomize the output of the hash,
we can then append this salt to
the plain text password
before performing the hash calculation.
The salt does not need to be secret,
but it does need to be stored
alongside the username and hash
result so that the application can
perform authentication checks as usual.
Some notes. You want to generate this salt
using a cryptographically
secure pseudo-random number generator.
For example, in Java, it is java.security.SecureRandom.
The salt length needs to be
at least the same length as
the output of the hash function.
That means for example,
if SHA256 produces 256 bit length output,
the salt needs to be at least 256 bits in length.
I mentioned SHA256 here,
but we don't want to use that hash function.
I'm going to talk a little bit more
about what a good hash function
to use a little bit later.
Another note is to generate
a new onetime salt for each user.
That means do not reuse
the same salt for more than one user.
The way you would want to store a password for
a new user is the following: First,
you want to generate that salt using the CSPRNG,
so the cryptographically
secure pseudo-random number generator,
and then you want to concatenate that salt
with the plain text password that the user has given.
Then the next step is to hash
the salt plus plain text together.
You have concatenated it.
Now, you want to hash that whole piece of data.
You want to hash using something called
a slow hashing function like bcrypt or PBKDF2.
I will get to a little bit later
why you would want to use a slow hashing function.
The last step is to store your new user record like this.
You would have a hash and then a salt,
the salt that you generated
and your username, for example.
Then other things that you want to add to this record.
Fundamentally speaking, you want to store
the results of the hash that you performed in step three.
You want to store this salt
that you used and your username.
That will be one record.
In order to perform authentication,
you want to first get
the salt that's associated with the username,
and then the next step is to concatenate that salt
with a plain text password that the user has given,
the user that is trying to authenticate themselves.
Then you want to hash
those results of the second step using
the same exact hash function that you
used when you stored the user information initially.
The last step is to compare the result of
step three with what is in the database.
If the result of step three matches,
then the user is authenticated.
A good rule to use is to perform the hashing on
the server side for both storing
and performing the authentication hashing.
Again, I want to make sure to be
very clear that in step two,
the plain text password is the one that is being
given as input in order to get checked,
not the plain text password that could have been stored.
Don't ever store the plain text password ever.
That's not what we want to do.
Now, we're going to talk about what it means to slow down
our brute force calculations with PBKDF2.
Remember how I mentioned that
you want to use a slow hashing function to
store your passwords or to store
your information and not the plain text password.
I want to point out that the salt
prevents the use of lookup tables.
Those are tables with precomputed hashes from a wordlist.
But a salt doesn't prevent brute force attacks.
The idea is you want to
slow down the hashing computation.
This makes brute force calculations
too slow to be useful.
In summary, we went over the previous videos
example of how not to
store user authentication information.
Then we talked about salting and hashing.
Then we mentioned how to slow down
brute force calculations using
slow hashing functions like PBKDF2 or bcrypt.
That's it for now. Thanks for listening.