Start a free Courses trial
to watch this video
In this video, we improve our authentication code by taking our passwords out of cleartext, and instead hashing them. Download code example
This video doesn't have any notes.
Related Discussions
Have questions about this video? Start a discussion with the community and Treehouse staff.
Sign upRelated Discussions
Have questions about this video? Start a discussion with the community and Treehouse staff.
Sign up[? Music ?] 0:00 [Think Vitamin Membership] [membership.thinkvitamin.com] 0:03 [PHP Authentication] [Password Hashing] 0:07 Jim Hoskins: Now that we have a simple working authentication system, 0:13 let's go back and see how we can improve it. 0:15 The biggest problem is that our passwords are stored in clear text. 0:17 Now, obviously, the passwords aren't visible to the user, but if someone 0:22 were to be able to access our source code or look over our shoulder or get the source 0:26 out of version control, they'd be able to see the passwords right there. 0:30 Now, that's pretty dangerous. 0:34 We don't want to be handing out our password. 0:36 So, instead of storing the clear text password, we should store a cryptographic hash. 0:38 A cryptographic hash is a function that takes an input and transforms it into an output. 0:42 Now, usually these outputs take the form of a fixed length of hexidecimal characters. 0:47 What makes them useful is that one input will always give the same output, 0:52 and you can't tell what the input is simply by looking at the output, and even if you 0:56 change one little bit of the input, the output will be changed completely. 1:01 You can't tell that two inputs are similar by just looking at the output. 1:05 So, what we can do is calculate the hash value from our passwords 1:10 and store those hash values. 1:14 Then, when a password attempt is submitted, we can hash it, compare the outputs, 1:16 and if they match, it's practically assured that the inputs were the same. 1:20 Now, it's possible that two different inputs could have the same outputs, 1:24 but the chances of that happening with two password linked strings 1:28 is astronomically small. 1:31 Now, there are two different functions you can easily use for hashing in PHP, 1:34 md5 and sha1. 1:38 These are named after the two hashing algorithms that they utilize. 1:40 Now, md5 is more widely used, but sha1 is going to be more secure, 1:44 and it has a larger output hash, thereby decreasing the probability 1:48 of a collision between two different input values creating a common output. 1:52 Now, from a practical perspective, md5 is secure enough, but if you have 1:57 the choice between md5 and sha1, why not go with sha1. 2:02 Now, let's look at how we can utilize this. 2:05 I've created a script called hash.php. 2:08 Now, this script is just a utility for us in order to hash our passwords, and we wouldn't 2:11 necessarily want to expose this on our public website. 2:15 It wouldn't be really harmful, but it does us no good. 2:19 So, it's just a utility script, and what it does is at the top of the page, it checks for a 2:22 submitted password, and then it runs it through the md5 function. 2:27 I've included a few different types of hashing, and we'll go over the salted ones 2:31 in a second, but if you want to use sha1 just uncomment this line, or if 2:34 you want to use md5 just use this line. 2:38 So, right now I'm just going to use an md5 hash, and the rest of it 2:41 just shows the result if there is one and a form. 2:45 So, going to our hash page, we can see it just has a simple password. 2:48 Now, if I type in adminpass and click go, we can see that 2:52 the result of that is this string right here. 2:59 Now, if I type it again, adminpass, it will always give us the same result, 3:03 and that's what makes a hashing function useful. 3:09 Now, if I were to say adminpast with a T, you see just by changing one letter 3:12 it's a completely different hash. 3:19 Then we go back to the code, and I'm going to change it so we're using a sha1 hash 3:21 because I prefer using sha1. 3:26 So, I'm just going to uncomment the sha1 line, 3:29 and I'm going to rehash our password with sha1. 3:32 So, I'm going to say "adminpass," and you can see it's slightly longer because 3:35 sha1 produces a longer output. 3:40 So, I'm going to go ahead and copy this, and we'll go to our auth.php, 3:43 and instead of adminpass we're going to put the password value here, 3:48 and let's go ahead and do the same thing for Jim's pass. 3:53 And we can take this value and replace this password. 3:59 So, that's part one. 4:05 We've hashed the passwords that are stored for us. 4:07 Now we actually have to modify our credentials valid function to hash the 4:09 requested password before comparing it. 4:13 So, what I'm going to do is I'm just going to replace this 4:16 because we're getting a little more complicated. 4:18 We're going to build it out a little bit more, and here we're doing the same check 4:20 as we did before of users of username being set. 4:23 If it is, then we get the hashed submitted password by calling the 4:26 sha1 function on our password. 4:30 We can get the correct hash password by just looking up the users of username 4:33 since we've already hashed them in the array. 4:38 And finally, we return that hashed_submitted = hashed_correct. 4:41 If they do not match, then they're not the same password and their credentials are invalid. 4:45 Now, if the user name is not found, we will return false. 4:50 So, let's go to our page and we will try to log in, 4:53 admin, and using our admin pass, and you can see that we've successfully logged in. 4:56 Hashing is a great first step, but you can secure your passwords even more 5:02 with a little bit of salt. 5:05 Since hashing passwords is a popular way to secure data, if your password hashes 5:07 are compromised, it still is possible that an attacker could figure out your password. 5:11 This is because attackers can hash commonly used passwords or even 5:17 exhaustive lists of random characters, and they can create 5:21 a lookup of those hashes to the passwords. 5:24 These tables are known as "rainbow tables," and many have been pregenerated 5:27 over large swaths of possible passwords. 5:31 Now, what we can do to protect against this is consistently prepend some string 5:34 or salt to our passwords before encoding them. 5:39 So, if we prepend a string like "toaster" before our passwords, 5:43 our hash will be different then if we just use a normal function on our passwords, 5:48 because in essence, we have changed the hashing algorithm. 5:52 Now, if an attacker knows the hash, they could generate new tables that included our salt, 5:56 but generating those tables takes an incredible amount of time and resources 6:02 compared to just using a pregenerated one. 6:05 For added security, you could generate a unique salt for each user, 6:09 thereby making it difficult to attack multiple users on your site 6:13 should your salts be compromised. 6:16 So, let's look at how we could implement that. 6:18 First, in our lookup function, we're going to create a salt. 6:20 Now here, I've created some real words, some junk. 6:24 We want it to be fairly long and fairly random. 6:28 If it's only a couple letters, then there's a chance that the pregenerated 6:30 rainbow tables might contain your salt plus your password, 6:33 and then somebody could figure it out. 6:38 If they're fairly long, the longer and more random the better they are, 6:40 the more they're going to be resistant to attacks. 6:43 So, we just take the salt and before we hash our password, 6:47 we prepend it to our password. 6:50 So, we're going to say "salt" and then prepend and then concatenate to our password. 6:53 So now, these passwords will no longer match now that we've salted it, 6:59 so we do have to regenerate our passwords here. 7:03 Now, this is important because if you change your salt, 7:07 all of your password hashes will be invalid. 7:10 So, you must keep your salt safe, otherwise you're going to not be able to 7:12 let your users log in without regenerating all of their passwords. 7:16 So, we're going to keep this safe, and we're going to save this out, 7:20 and let's go back to our generator, our hash.php. 7:23 And let's go ahead and comment out our result with no salt, 7:27 and instead, uncomment the salted sha1. 7:33 So, as you can see here, we've done the same thing. 7:36 We've prepended salt to our password, and I've made sure to use 7:38 the exact same salt over here that we are in our auth.php, 7:42 and that's important because a different salt will return a different end value. 7:46 So, let's go to our hash generator, and we'll just type in "adminpass" to create our admin one. 7:52 So, going back to auth.php, we're going to replace our value, 7:57 and you can see that it's changed, and I've also changed the Jim password as well. 8:03 So, let's go to our page. 8:07 We will log out, and we'll see if we can still log in, 8:09 admin and then adminpass, and it still works. 8:13 So, you can see, now we have a much more secure page here. 8:18 If someone were to see our source code, they wouldn't be able to tell that the 8:20 actual password to get in was adminpass, or Jim's pass in this case. 8:24 In upcoming videos, we'll build a more robust database-backed user system 8:29 for our authentication system. 8:33 [Think Vitamin Membership] [membership.thinkvitamin.com] 8:36
You need to sign up for Treehouse in order to download course files.
Sign upYou need to sign up for Treehouse in order to set up Workspace
Sign up