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.