WEBVTT 0 00:00.570 --> 00:00.960 All right. 1 00:00.990 --> 00:05.780 So now it's time to level up to the next level of security. 2 00:05.880 --> 00:10.630 And in this lesson we're going to cover something called hashing. 3 00:10.680 --> 00:18.510 Now previously we've already looked at encryption, so taking the user's password and securing it using 4 00:18.600 --> 00:26.760 an encryption key and then using a particular cipher method be it a Caesar cipher or the Enigma cipher 5 00:26.880 --> 00:33.180 or a modern cipher method like AES which is what we enabled on our database. No matter which way we 6 00:33.180 --> 00:33.570 chose 7 00:33.600 --> 00:39.840 we always had a password, a key and we ended up with some ciphertext which will make it hard for people 8 00:39.840 --> 00:43.650 to be able to immediately guessed what our users password is. 9 00:43.650 --> 00:49.770 So for example if we took a password like qwerty and we use the Caesar Cipher method and we decided 10 00:49.770 --> 00:56.730 to shift it by one, then our encryption key is the number one. And that creates the ciphertext where every 11 00:56.730 --> 00:59.690 single letter is shifted up by one. 12 00:59.910 --> 01:06.150 Now in order to decrypt this all you have to do as long as you know what the key is then you can simply 13 01:06.150 --> 01:12.860 shift all of the ciphertext down by one and you end up with the original password. 14 01:12.870 --> 01:18.200 Now the Caesar cipher is a very very weak encryption method. 15 01:18.210 --> 01:25.860 It's incredibly easy to figure out what the original text was even if you didn't have a key. And just 16 01:25.860 --> 01:31.080 to illustrate what bad things can happen when you have a weak encryption system 17 01:31.080 --> 01:37.170 I'm going to tell you a story from history that tells us why we should not be using a weak encryption 18 01:37.170 --> 01:38.250 system. 19 01:38.250 --> 01:45.240 So back in the 1500s on this island that we now call the United Kingdom, there used to be two large 20 01:45.270 --> 01:46.230 areas. 21 01:46.230 --> 01:48.200 One was Scotland, 22 01:48.510 --> 01:53.910 and the other was England. and they were ruled over by two queens. 23 01:53.910 --> 01:57.630 Scotland was ruled by Mary Queen of Scots who was a Catholic 24 01:57.630 --> 02:02.160 and England was ruled over by Queen Elizabeth the first. 25 02:02.160 --> 02:07.800 Now these two ladies between them controlled the land that we now called the UK. But they each wanted 26 02:07.800 --> 02:10.350 to have more power and more land. 27 02:10.830 --> 02:12.480 So what did they do? 28 02:12.510 --> 02:21.330 Well Mary Queen of Scots who ruled over Scotland decided to plot with her friend Lord Babington to try 29 02:21.420 --> 02:23.760 and assassinate Queen Elizabeth. 30 02:23.760 --> 02:29.530 That way she would be the legitimate heir to both the English and Scottish throne 31 02:29.670 --> 02:33.750 and it was kind of a Game of Thrones kind of situation going on back then. 32 02:33.960 --> 02:40.710 But in order to mobilize their forces or try to come up with some sort of secret plan they decided to 33 02:40.710 --> 02:44.520 send letters to each other using ciphertext. 34 02:44.520 --> 02:52.350 So they came up with a system to encrypt their letters to each other such that if it fell into the wrong 35 02:52.350 --> 02:59.510 hands the subject of the letter wouldn't be revealed and they wouldn't end up being tried for treason. 36 02:59.520 --> 03:05.730 But the problem was that the encryption method that they used which was a letter substitution method 37 03:05.970 --> 03:11.660 similar to the Caesar cipher was a very weak form of encryption. 38 03:11.700 --> 03:20.700 And Queen Elizabeth had a chief decoder who ended up deciphering their letters and figuring out what 39 03:20.760 --> 03:22.770 their encryption key was. 40 03:22.950 --> 03:30.870 So he decided to take this encryption key and write a letter back to Lord Babington to try and get him 41 03:30.870 --> 03:34.280 to reveal all of the co-conspirators. 42 03:34.470 --> 03:38.250 And what was the end result of having their weak encryption system? 43 03:38.250 --> 03:45.750 Well Queen Elizabeth decided to accuse Mary Queen of Scots of treason and hence she ended up having 44 03:45.750 --> 03:47.280 her head chopped off. 45 03:47.280 --> 03:51.900 So this is not what you want to happen to you or your website. 46 03:52.470 --> 03:59.820 So weak encryption systems can end up putting user passwords at risk and your company might end up metaphorically 47 03:59.820 --> 04:06.120 decapitated such as in the case of companies like TalkTalk or Equifax where they ended up getting hacked 48 04:06.300 --> 04:09.000 and lost a lot of the trust of their users. 49 04:09.000 --> 04:14.880 Now if you're interested in more stories like this and to learn more about cryptography and encryption 50 04:15.120 --> 04:20.100 there's a really great book recommendation I would make called THE CODE BOOK by Simon Singh. It contains 51 04:20.100 --> 04:22.940 stories like the one I just told you and more. 52 04:23.040 --> 04:26.190 So if you're interested in this go ahead and read more about it. 53 04:26.250 --> 04:30.860 Now how can we make our password more secure? Now at the moment 54 04:30.870 --> 04:38.340 the biggest flaw in our authentication method is the fact that we need an encryption key to encrypt 55 04:38.370 --> 04:45.780 our passwords and decrypt our passwords. And chances are that if somebody is motivated enough to spend 56 04:45.780 --> 04:52.920 time and hack into your database then it's probably not that difficult for them to also be able to get 57 04:52.920 --> 05:00.210 your encryption key even if you've saved it in environment variable or somewhere secure on your server. 58 05:00.470 --> 05:03.280 So how can we address this weakest link 59 05:03.320 --> 05:05.660 the need for that encryption key? 60 05:05.700 --> 05:08.650 Well here is where hashing comes into play. 61 05:08.750 --> 05:15.770 Whereas previously with encryption we needed that encryption key, hashing takes it away and no longer 62 05:15.860 --> 05:19.070 requires the need for an encryption key. 63 05:19.700 --> 05:26.270 Well then you might ask, "Well if we don't have an encryption key how can we decrypt our password back 64 05:26.270 --> 05:27.890 into plain text?" 65 05:27.890 --> 05:35.960 Well the secret is you don't. Let's say a user registers on our website and they enter a password to 66 05:35.960 --> 05:37.220 register with, 67 05:37.430 --> 05:45.260 we use something called a Hash function to turn that password into a hash and we store that hash in 68 05:45.260 --> 05:46.730 our database. 69 05:46.730 --> 05:56.210 Now the problem is that Hash functions are mathematical equations that are designed to make it almost 70 05:56.210 --> 05:59.100 impossible to go backwards. 71 05:59.480 --> 06:05.690 It's almost impossible to turn a hash back into a password. 72 06:05.690 --> 06:12.590 "How is this possible?" you might ask. How is it possible that you can turn a password into a hash very 73 06:12.590 --> 06:19.360 quickly and easily but make it almost impossible to turn that hash back into a password? 74 06:19.370 --> 06:21.170 Well here's a question. 75 06:21.170 --> 06:28.580 Let me ask you, what are the factors of 377 other than 1 and 377? 76 06:28.580 --> 06:32.630 So basically I'm saying 377 is not a prime number. 77 06:32.630 --> 06:40.760 Not only can you divide 377 by 1 and 377, but there's also two other numbers 78 06:40.760 --> 06:42.260 that you can divide it by. 79 06:42.410 --> 06:45.770 Now it's your job to figure out what those numbers are. 80 06:46.670 --> 06:47.920 So what might you do? 81 06:47.930 --> 06:50.050 Well you might divide it by 2. 82 06:50.060 --> 06:50.420 OK. 83 06:50.420 --> 06:52.640 So that becomes 188.5. 84 06:52.640 --> 06:53.780 That's not a whole number 85 06:53.840 --> 06:55.730 so 2 is not a factor. 86 06:55.820 --> 06:57.110 What if you divided by 3? 87 06:57.140 --> 07:03.000 Well that becomes 113.33... recurring which is also not a whole number. 88 07:03.020 --> 07:05.320 So 3 is not a factor either. 89 07:05.730 --> 07:12.350 And you might go through this process for a long time tediously going through number by number. 90 07:12.530 --> 07:19.520 Well then you might arrive at the point where you divide 377 by 13 and you end up with 91 07:19.520 --> 07:20.180 29. 92 07:20.600 --> 07:25.380 So 13 and 29 are the answers to this question. 93 07:25.460 --> 07:32.240 They are the only factors of 377 other than 1 and 377. 94 07:32.240 --> 07:39.250 And as you can see, that process of getting to this point of finding those two factors took us a while 95 07:39.290 --> 07:39.740 right? 96 07:39.740 --> 07:40.930 It wasn't that easy. 97 07:41.390 --> 07:47.050 But consider if I asked you a different question. If I said to you can you multiply 13 by 98 07:47.050 --> 07:47.490 29? 99 07:47.870 --> 07:51.400 Well you would be able to do that really quickly and easily. 100 07:51.410 --> 07:56.590 It would take you almost no time at all to figure out that the answer is 377. 101 07:57.440 --> 08:03.920 So here is a very very simplified version of a Hash function. 102 08:03.920 --> 08:12.200 So going forward multiplying 13 by 29 is really quick and easy but going backwards trying to get back 103 08:12.200 --> 08:18.860 those numbers 13 and 29 starting from 377 is very very time consuming. 104 08:19.310 --> 08:26.030 So this is essentially how a Hash function works, just add a little bit more complexity and you end up 105 08:26.090 --> 08:28.160 with a real hash function. 106 08:28.160 --> 08:35.830 So they're designed to be calculated very quickly going forwards but almost impossible to go backwards. 107 08:35.930 --> 08:43.730 And by almost impossible I simply mean that using current levels of computing power it would take far 108 08:43.730 --> 08:46.330 too long to make it worthwhile for the hacker. 109 08:46.700 --> 08:53.480 So let's say that to calculate the hash going forward it takes a millisecond but to go backwards it 110 08:53.480 --> 08:58.510 takes two years, then that hacker probably has better things to do with his time. 111 08:58.520 --> 09:05.150 So when a user tries to register on our website then we ask them for the registration password which 112 09:05.210 --> 09:11.660 we turn into a hash using our Hash function and then we store that hash on our database. 113 09:11.750 --> 09:19.310 Now at a later point when the user tries to log in and they type in their password, then we again hash 114 09:19.370 --> 09:27.110 that password that they typed in to produce a hash and then we compare it against the hash that we have 115 09:27.110 --> 09:29.120 stored in our database. 116 09:29.660 --> 09:36.650 And if those two hashes match then that must mean that the login password is the same as the registration 117 09:36.650 --> 09:37.900 password as well. 118 09:37.970 --> 09:45.320 And at no point in this process do we have to store their password in plaintext or are we able to reverse 119 09:45.320 --> 09:49.120 the process to figure out their original password. 120 09:49.190 --> 09:53.330 The only person who knows their password is the user themselves. 121 09:53.330 --> 10:02.080 Now previously we saw that by using the Enigma machine as long as we knew what the settings were for 122 10:02.080 --> 10:05.540 the Enigma machine which is basically the encryption key 123 10:05.560 --> 10:06.260 right? 124 10:06.310 --> 10:08.380 As long as we knew what that was 125 10:08.680 --> 10:13.410 then I can decode it by setting it to the same encryption key. 126 10:14.890 --> 10:19.430 And we end up being able to retrieve the original text. Now 127 10:19.440 --> 10:27.400 however, if I was to go and change this to a hash function instead, then you can see that when we try 128 10:27.400 --> 10:35.680 to decode this using the same hash function MD5, we get the error that "Decoding step is not defined 129 10:35.740 --> 10:38.990 for Hash function" because you can't really go back. 130 10:39.100 --> 10:41.540 That's the whole point of the Hash function 131 10:41.650 --> 10:45.850 and this is what will make our authentication more secure. 132 10:46.720 --> 10:49.640 So let's go ahead and implement this in our code. 133 10:50.140 --> 10:56.440 So first things first let's go ahead and install MD5, the package. And then all we need to do is 134 10:56.440 --> 11:04.060 just you require it and then use it to Hash a particular message or in our case the password. 135 11:04.870 --> 11:13.480 So let's go over here and let's remove Mongoose encryption and remove this plugin from our user schema 136 11:13.870 --> 11:17.640 and instead we're going to require "md5". 137 11:21.480 --> 11:27.440 And when the user registers instead of saving their password which is what we got from the req. 138 11:27.480 --> 11:35.690 body, we're going to use our Hash function, MD5, to turn that into a irreversible hash. 139 11:35.700 --> 11:37.950 So let's give that a go. 140 11:37.950 --> 11:45.480 So firstly we're going to run our app.js and we're going to open up our website and register a 141 11:45.480 --> 11:56.320 new user who will call user@hash.com and we will give them a password of 123456. 142 11:56.340 --> 11:57.570 Go ahead and hit register. 143 11:58.020 --> 11:58.320 OK. 144 11:58.320 --> 11:59.340 Success. 145 11:59.340 --> 12:06.900 So that means our users been saved successfully into our database and we can see that the email is still 146 12:06.900 --> 12:15.660 left as is so that we can search through it but the password is now a hash that's been created by passing 147 12:15.840 --> 12:16.690 a password, 148 12:16.710 --> 12:19.950 123456, through that Hash function 149 12:19.950 --> 12:20.860 Md5. 150 12:21.030 --> 12:23.450 And this will be impossible to reverse. 151 12:23.550 --> 12:29.670 We can't decrypt it and we don't have any sort of encryption key that leaves it vulnerable. 152 12:29.670 --> 12:33.950 So now we need to figure out what to do with the log in step. 153 12:33.990 --> 12:40.800 Now the important thing that you need to remember with hashing is that when you run the Hash function 154 12:41.220 --> 12:48.240 on the same string, the hash that's created is always going to be the same. 155 12:48.540 --> 12:55.470 So for example if I decide as a console log MD5 and I pass through the string 12345 156 12:55.470 --> 12:56.550 6, 157 12:56.880 --> 13:04.950 Then when I hit save and nodemon reruns this app.js, you can see this is the hash that's generated 158 13:05.460 --> 13:12.420 and this matches exactly with the hash that was generated here previously when I tried to register the 159 13:12.420 --> 13:22.080 user and hashed the password that they typed in. So this is how we're able to later then compare. 160 13:22.080 --> 13:29.580 So when the user tries to log in, we'll hash the password that they tried to type in using the same Hash 161 13:29.580 --> 13:37.710 function MD5, and then we'll compare the outcome of this with the hash that's stored in our 162 13:37.710 --> 13:38.700 database. 163 13:38.700 --> 13:45.120 And if they match then that must mean that the initial password that they typed in must have been equal 164 13:45.150 --> 13:51.810 to the initial password that they registered with because after hashing they matched exactly. 165 13:51.810 --> 14:00.720 So now we're going to compare the hash that's inside our database with the hashed version of their password 166 14:00.930 --> 14:03.630 and see if it matches to be able to log them in. 167 14:03.630 --> 14:09.740 So let hit save and let's go and go back to our home page. 168 14:09.780 --> 14:17.380 Try and log in our user, user@hash.com and the password was 123456. 169 14:17.370 --> 14:24.900 Let's go ahead and login. So we've managed to successfully log in because those hashes match. 170 14:24.900 --> 14:28.610 And this is very simply how hashing works. 171 14:28.620 --> 14:35.940 So now when a user decides to hack into our database, all they have all these hashes in the place of 172 14:35.940 --> 14:43.920 our passwords and because of the way that hashing algorithms work you can't reverse this back into the 173 14:43.920 --> 14:47.220 plain text of the original password. 174 14:47.220 --> 14:49.290 So that's all very well and good 175 14:49.350 --> 14:56.640 and theoretically our passwords are a lot more secure than when we simply encrypted it because we had 176 14:56.640 --> 14:59.690 the vulnerability of that encryption key. 177 14:59.940 --> 15:05.070 As soon as somebody discovers the key then all of our encryption was for naught. 178 15:05.100 --> 15:12.390 Now hashing also comes along with its own problems though because as soon as you come up with a problem 179 15:12.810 --> 15:16.570 then some motivated hacker will come up with a solution. 180 15:16.680 --> 15:22.270 And in the next lesson I'm going to show you how we can hack our users passwords. 181 15:22.350 --> 15:24.750 So for all of that and more, I'll see you there.