Godot Multiplayer - Salting and Hashing Passwords | Godot Dedicated Server #9

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
in this godot tutorial i'll be teaching you how not to do things are you serious yes i'm absolutely serious so by the title you probably figured out we're going to be sorting and hashing passwords today so we can securely store them on the database of our server so today i'm going to be teaching you a couple of bad practices and before we can really get into why i chose to do so or or basically why i'm forced to do that let's first dive into hashing and well various types of hashing and where which types of hashing is being used there are two types of hashing functions that are relevant to this topic on one hand we have the slow hashing functions and on the other hand the fast hashing functions and their name pretty much implies how they execute and what the difference between the two is one executes fast the other one intentionally slow so before we can determine which of the two types will be best for hashing our passwords we have to consider what we're actually trying to secure from and we are securing this database by hashing the passwords from brute force attacks so what is a brute force attack a brute force attack starts with somebody gaining access to your server and being able to download or copy or read the user and password database that you have on your server now these passwords are not going to be useful as they will be hashed however a hacker could brute force the hash open and thereby revealing your password the way he does that is basically there's this long ass list of let's say a million or two million passwords that are very common in the world because people are pretty bad at choosing passwords and he's just basically just going to run that through the same hashing function that we have used to create the hash in the first place and he's going to look for a match and as soon as he found the match then he knows the original input that created that hash and therefore he knows your password now once that list of 1 million or 2 million options or common passwords is exhausted you could still continue to simply try more options with more randomized values and at some point he will find it the only question is how long and that's really where the fast and the slow come come into play so let's take the sha256 algorithm it's an algorithm that's integrated into gt script we've used it before so i probably will be a good one to to use as an example let's say we have a seven character password let's say we only use lowercase that means has 26 options the alphabet per character and that means we have 26 to the power of 7 total options for our password which would be 8 billion some quick math for you um now you'll be surprised maybe to hear that a not even super high tech but a reasonably modern gpu set up with the right script and in the right environment not even that difficult to do can test or hash about 2 million passwords per second of the sha256 hashing function that's quite a lot and it means it takes about 2 000 seconds to find your password and yeah i know that 2 million times 2 000 doesn't make 8 billion but statistically he will only have to test the first 50 because statistically your password will be uh 50 of the time in the first 50 percent of the passwords he tests especially if your password is made out of normal words that can be found in a dictionary or even very standard passwords then you will have it even much faster so with 2000 seconds the password is known in about 33 minutes that is worrying and that's why we have also got the slow hashing functions the slow hashing functions are intentionally slow and instead of a couple of million of these per second they will only be able to couple maybe one two three even maybe a dozen and that of course is going to seriously increase the amount of time necessary before they have a positive hashing hit basically so preferably we use the slow hashing functions for our passwords the only problem is they are not integrated in gdscript gdscript only has fast hashing functions and not the integration that you see in c plus or c sharp or python for the slow hashing functions so that puts me as a creator that is trying to teach you best practices in a little bit of a dilemma do i skip this tutorial no do i introduce all kinds of plugins and add-ons or external services and make this tutorial even more complex as it already is well i don't prefer that because i basically promise you 100 gd script code up multiplayer thing so i'm really only left with the third option that's just to teach you best best bad bad practices not best practices watch out so what i strongly advise you to do is to take these teachings with a grain of salt and mostly learn from what i've just explained you about brute force attack and how we can counter them and to keep the patch notes of godot 4.0 4.1 4.2 give a close eye on them so that as soon as godad has implemented something like argon 2 or b script that we can replace this little piece of code i'll be teaching you today for something that is tried and tested and known to be a good password hash so that's basically the message that i got for you to send you off with i think i talked long enough and for this introduction and let's get coding so we're starting the code off at the authentication server so in the authenticate script on here we have created the create account function in the last tutorial and i've told you in the last tutorial we'll be changing some of that code to ensure we're hashing and solving the password as you can see i've changed this part of the code these three lines are different than the one line of code you're going to be having in your project if you're following along in the old project it said player data player id's username password is password instead of hashed password because we were taking this input from the client and it didn't have to be sold of course what we're doing now is now we're storing the hash password we defined up here and the salt that we have defined up there for the salt we're going to generate the salt and salt is nothing more than a random string of characters that we're going to be adding on top of the password and we do that so that when two users have the same password if we wouldn't be sorting it and we would only be hashing the password these players are gonna have the same hash outcome because of course the same input is the same outcome now if somebody were to try and brute force our user and password database and he would have a hit on one of the hashes he could then check the entire database of all the users to see if there's another user with exactly the same hash and if that's the case that means that both of these users have the same password and instead of one account he has hacked two accounts at the same time or three or four or five by using these solds we are no longer susceptible to such a text because we have a random standard string that is unique to every player added on top of the password so when we create a new account we also have to create a new sold for that player because that's unique to the player that sold doesn't have to be secret in fact it's going to be stored just next to the password on the user database for the sold we're generating the sold and we for that we pretty much use exactly the same function as we did for the network token verification in tutorial number five or six so we're simply gonna take a random integer after we have randomized the seed of the engine and we're just going to use that sha256 hashing function to get a completely random 64 character long string well we'll print that so we can see what's going on got a couple of prints left and right so i can demonstrate to you how this actually works so next up once we've got the sold we're gonna use the password provided by the player together with the sold that we just generated and we're gonna put that into the generate hatched password to create our hash password that is right here and there's a couple of things i do in here that i'll explain one by one first we are printing the system time up and down i'm only doing that for demonstration to you right now you can delete those lines out of it once you're done we are going to be taking that password that came down into the generate hash password um we are going to be saving that right here then we determine how many rounds we are going to be hashing it because instead of having one slow hashing function i'm going to be using a fast hashing function again that sha256 and we're just going to be doing it many times over and over and over and over again re-adding the salt every single time until it is slow and that sounds like well i just made it up out of nowhere but actually i didn't repeating that hash over and over and over again is actually one of the core concept of b script one of the slow hashing algorithms so i am taking a tried and tested practice out of one of the slow hashing algorithms and i'm implying it and making the function myself so it's not like completely pulled out of thin air it does have like a scientific basing on it but it's just not best practice to create a function yourself normally you would just use a stamped tried and tested implementation so back to the code we're determining how many rounds we're going to be doing over and over again and this basically functions as power 2 to the power 3 which is of course 8. i'll be using 2 to the power of 18 later on so we're going to be doing this hash 262 thousand times over again and if you want this to be longer you just make 2 to the power of 19 and suddenly it's more than half a million but for now we'll just use 18. then while rounds is um bigger than zero uh we're going to be running this while loop and this while loop is like i said it's going to run 260 000 times so we're going to be taking that hash password we add the solvent on top of it so that makes 128 characters we put it through the hashing function thereby it becomes 64 characters again and then we just go again and we add the salt and we go again then we add assault and we go again and so forth and so forth and so forth so once that was all done and the rounds are finished we're gonna print that final hash we print that operating time so you can see how long it takes and there we have our hashed password then of course instead of just saving the password uh bear and naked we're gonna be saving the hash password and we'll save the soul along for with it because we're gonna need to sold the player makes when the player makes a login attempt so how does it all work you might be wondering well i got a little bit of a test setup here so i'm not going to actually be trying logging in just under the ready function when i start the authentication server up i've defined a salt this is a sort i generated previously and i'm going to be pushing this is my password with an underscore in between 88 exclamation mark as my password so now when i press play right here in the output you can see the authentication server started um and this is my password i have forgotten one thing i need to remove the comment under the print here we go again here you can see that every round the password or the hash of that password is completely different because every time we take the output of the previous round we add the salt on top of it which stays the same and therefore the output is different different different different different until we finally have our final hash and that will be the password we're actually storing so here we got the time this is the time stamp and the last three numbers are the milliseconds so this is 129 milliseconds and right here we got 144 milliseconds so that is 15 milliseconds for eight rounds but this print takes up a lot of processing power so if i remove this print right here from the function and we'll run it now you can now see that this is 202 and it's 205 so we went from 15 milliseconds to 3 milliseconds just because we are not printing that output anymore so now if you were to ask me like how long does it take to do 262 000 times well we'll just change the 18 here we'll replay this code and we'll see that now we got here five seconds and 838 milliseconds and here we got six seconds 574 so this um execution took about 0.7 seconds on my machine so that means the hacker if he were to do this or have to do this through a brute force attack he would be able to test about two passwords per second and that is of course much less than two million passwords per second now my system might not be optimized for this um so it could be that the hacker is considerably faster but one thing we can be sure of is that we have made it 262 000 times slower than it would have otherwise taken but we're not completely done yet because now we have a hashed password in our database but we're still comparing that hash password to the naked password once we authenticate a player on a login attempt so we have to change that code as well that code is on the same script so we can just stay on the authentication server we scroll up a little bit to our authenticate player function which we coded in episode number three and here we have if the player the username doesn't exist we have a false login and here we test if the password that was provided by the player is equal to the password which will of course now always be false because we are matching naked versus hash password so we're going to change this if else if else statement and we're going to split them up into two if statements like so we first check if the username exists that stays the same but if the username does exist we are now going to be retrieving the sort we can only retrieve the sort once we have verified that that username exists because otherwise we're going to be looking for a key in a dictionary that isn't existing and that of course throws an error so we retrieve the salt from the player data where we stored it and then we're going to be using the password provided in this function to the generate hash password with the retrieve sold so that brings us into the same function as i just explained and we're just going to be basically hashing the password provided by the player now as we have done that we can now compare that hashed password with the password that we have in our database thereby we are fixing that matching up again now of course we can only do this if the user is known and by splitting that if else if else statement into two if statements we have to tap this one along that it only runs under else and of course this randomize network verification token process only needs to run if the result is true so we're going to tap this or indendent this one forward as well so now we have fixed our login sequence and of course we just can return the results as per normal to the player now there's one more thing that i want to change because right now in the first round once we start hashing the password we still have the naked password so the first attempt of hashing is going to just take the normal password there's not really anything wrong with that but now that we're busy with all this hashing anyway it may not be a bad idea that the server is never going to be receiving the naked password at all it's not very common that once we've already implemented the ssl encryption over the line that there's every gonna be any issue with it but if we can make sure that the server never really knows that password that's always better than when it is available here so allow me to take you with me really quick to the client side of things and right here on the gateway script of the client and here we have the request for login and the request for create account and instead of pushing the password here you can see that i've done the first hash the first round let's say although there's no salt added here yet we have already pushed a hashed value to the server so the server is now not going to be receiving a naked password the server is going to be receiving a 64 character long random string based on the password of the player so with this we have a complete hashing function that is totally not best practice i can't state that enough i know i'm basically just sort of undermining my own believability as a creator and a tutorial and a developer as a tutorial yeah as a tutorial why not why not it's a crazy episode anyway so with this i think we're done that was it for today guys hope you enjoyed it if you did smash that like button hit subscribe and don't forget that little bell icon to make sure that you don't miss out on the next video in the next couple of tutorials we're gonna get into something that i know a lot of you have been looking forward to we're finally going to be syncing up players and the world so stay tuned for those tutorials i'll see you then until then keep on gaming keep on coding see you later guys
Info
Channel: Game Development Center
Views: 2,716
Rating: undefined out of 5
Keywords: Godot Multiplayer, Godot Password Hashing, Godot Password Salting, Godot Hashing and Salting, Godot Storing Passwords, Godot Creating Accounts, Godot Network, Godot Networking, Godot Dedicated Server, Godot Multiplayer Server, How to make a multiplayer game, Godot MMO, Godot Beginner Tutorial, Godot 2d Tutorial, Godot Tutorial, Godot
Id: YIi9JEKDSMo
Channel Id: undefined
Length: 16min 59sec (1019 seconds)
Published: Sun Nov 08 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.