[Tutorial] How NOT To Store Your Users' Passwords
#1

How NOT To Store Your Users' Passwords

By Sasinosoft
The first thing we must be aware of when programming anything that will ask the user to enter a password, is that the user is giving us their trust. It is our duty to keep their password as safe as possible, so that in case of attack to our servers, the attacker will not be able to read their password. You might think that "it is just a game", so the security of the game accounts is not so serious, but a poll showed that 59% of people use the same password everywhere or almost everywhere. [source] If the attacker gets access to your game database, he will most likely obtain all your users' nicknames and passwords, and if they are not properly hashed, then you have made his work easier. After getting this information, the attacker will proceed to check for each user if he is registered on the main websites, such as Go0gle, Microsoft, mail providers, using the passwords and user names he just stole.
Here are a few hints to make his work harder.

1. DO NOT Store Passwords In Plain Text

It is believed that at least 30% of the websites store the passwords in plain text. [source] This is really a shame, and it must come to an end. If any website emails your password back in plain text, then he is surely storing your password as such, and compromising your security in all the websites that you used the same password.

You must never do so. In the case of a San Andreas Multiplayer server, as soon as you receive the user password in the inputtext parameter of OnDialogResponse, you must one-way hash it. Fortunately, the developers of SA-MP added the SHA256_PassHash function in version 0.3.7 R2-1, so there is no more excuse for those who don't like to use external plugins. [great tutorial]

Said that, I will also add that since there are better algorithms than SHA-256, it would be better if you used another one: bcrypt (the best, as I will show in the next section), SHA-512 or Whirlpool. On SA-MP Forums you can find plugins for bcrypt [link], SHA-512 [link] and Whirlpool [link]


2. DO NOT Simply Hash The Password And Store it

Hashing the password and store it will add very little security; most users' passwords are simple words or numbers which can be found in dictionaries. If this is the case, the attacker will easily detect the password of the user, simply by searching the hash in rainbow tables; these are per-algorithm tables which already contain the hashes of the most common passwords and more, and they are publicly available on the internet. [example]

To avoid this problem, and force the attacker to use brute-force attacks, thus wasting his time, money and energy, you must put salt on your passwords.


A prudent programmer putting salt on the password of his users.
The salt is a value that is concatenated to the password before hashing it, and there are different ways to do this, and different opinions about how this should be done. [tutorial for SA-MP - Whirlpool] The salt is unique for each user, and it is never secret: its value is stored in plain text into the database at the moment of registration, and it is read by your program when the user attempts to log in.

3. DO NOT Use The Username As Salt

If your SA-MP Server does this, and another website that your user is registered on with the same username and the same password does the same, both databases will contain the same password hash for the user. If the attacker, after getting a copy of your database and that of the other website, notices this coincidence, then he will most likeley focus on this particular user.

If you implemented a system to let the user change his password, you are then going to hash it with the same salt as before. This needs to be avoided.

The best practice is to generate a random string the first time the user registers, and to store it into the database in a separate column. When the user wants to change his password, your program will generate a new random string, and update the value in the database.

4. DO NOT Write Your Own Hashing Function

Do not do this, unless you work for the NSA and your algorithm has been tested for years. Do not do this even if you have studied cryptography and security. This is because, even if you think that your algorithm is strong enough, it has not been tested enough against all the possible kinds of attack. Do not risk, and if you have written one, just keep it as your personal project.

5. Use bcrypt
In this post I mentioned different hashing algorithms whose implementations are also available for SA-MP Servers. I must also say that the best option you have is to use bcrypt.
The primary advantage is that bcrypt, unlike the other algorithms mentioned here, aims at being slow to execute, especially on GPUs. When we are computing our hash during user registration or login, we don't care if it takes 1 second or more, because most likely the user will not notice it, instead we really care about the attacker being as slow as possible at brute/dictionary attacking our hashed password. SHA and Whirlpool are aimed at being as fast as possible to execute, and while this means that the user's password is checked in the blink of an eye, it also means that the attacker is able to crack the password in fewer time (with the appropriate equipment).
By using bcrypt, we make almost impossible for an attacker to crack the password, definitely not worth it for him.
Another advantage is that bcrypt will generate the salt for you, and you will have to do nothing.

6. Additional Tips
  • Also put pepper. Pepper is another value that is added to the algorithm before the final hash, but instead of being a different value for each user, it is a single constant string which is used for every hash, and it is secretly hardcoded in your code. Of course, after your first user is registered, you must never change it again.
  • Force the user to use a password of a certain minimum length, and made of multiple words.
  • In your register dialog, tell the user not to use the same password as other websites or SA-MP Servers, and not to tell his password to anyone.
  • Ask the user to input his password twice during registration and password changing procedure.
  • Kick the user and prevent him from logging in again for a certain time if he fails to log in for a certain number of times. This makes unpractical using direct brute force attacks to your server.
  • Implement a system to change the password, and encourage your users to change it when they feel it is compromised.
Reply
#2

In addition to this guide I'd like to invite those who are interested to watch this video:

https://www.youtube.com/watch?v=8ZtInClXe1Q
Reply
#3

You're still storing them, so this should've been like How to use a proper way of storing passwords by salting hashing or using an existing plugin.

Reply
#4

Quote:
Originally Posted by Robin96
View Post
In addition to this guide I'd like to invite those who are interested to watch this video:

https://www.youtube.com/watch?v=8ZtInClXe1Q
Thanks for the contribution, great video and great idea to post it as first comment.

Quote:
Originally Posted by RogueDrifter
View Post
You're still storing them, so this should've been like How to use a proper way of storing passwords by salting hashing or using an existing plugin.

Yes, of course in the end you will have to store them, but I wanted to say something more like "the ways that you must not use when storing your users' passwords".

Quote:
Originally Posted by Y_Less
View Post
This actually isn’t a good idea. The trend in passwords is towards things that are hard for people to remember, but really easy for computers to guess, since they literally don’t care about the difference between S and $. Meanwhile people will try and meet the requirements in the simplest way possible, with something like p4S$word - and they all think they’re really clever because they used @ instead of a, which is not clever at all and all the good crackers know about literally every replacement scheme. A MUCH better scheme (known as “correct horse battery staple”) is to have the user select four random words (there are services for this, but they tend to use a reduced word set - just flick through a dictionary, or get a word from the back of a shampoo bottle or something):

glossy lock pillar stinky


VASTLY easier to remember, and VASTLY harder to crack.

See the XKCD comic that introduced it:

https://www.xkcd.com/936/
Thanks. I think that what you posted it is the perfect way to select a password, and if I remember correctly my teacher one day talked about this. I updated my post with a more correct information.
Reply
#5

Did you have to put that famous chef Nusr Etmiami's pic there lol
Reply
#6

Quote:
Originally Posted by Y_Less
View Post
Another thing, mentioning BCrypt as a side-note isn't great. That should be front and centre, pretty much "how to not store passwords - by not using BCrypt (or better)". It really needs to be stressed a lot more (especially as it deals with rounds and salts automatically, instead of relying on users to understand those).
Thank you. Updated, I added a section for bcrypt.

Quote:
Originally Posted by Uproar
View Post
Did you have to put that famous chef Nusr Etmiami's pic there lol
Yes, because by using pictures, especially funny ones, will most likely make people continue reading to the end.
By the way I didn't know the name of that chef, thanks. I will go to Miami and eat at his restaurant
Reply
#7

Why to put a salt when its plain text and the hacker can access it easily? The thing I never understood....
And if its a database only hack if you made a random hashing method isn't seifer in this situation instead of using popular hash methods?
Reply
#8

Quote:
Originally Posted by jlalt
View Post
Why to put a salt when its plain text and the hacker can access it easily? The thing I never understood....
Because the salt alone is useless for the hacker. Even if he can read the salt, it will avail him little.
Instead of looking at pre-made tables with the common passwords, he is forced to recompute a dictionary of hashes made of common words with the salt attached to it.

Quote:
Originally Posted by jlalt
View Post
And if its a database only hack if you made a random hashing method isn't seifer in this situation instead of using popular hash methods?
An example: Linux is open-source, so everyone can see its source code; still it is much more secure than windows.
Reply
#9

Quote:
Originally Posted by Y_Less
View Post
This actually isn’t a good idea. The trend in passwords is towards things that are hard for people to remember, but really easy for computers to guess, since they literally don’t care about the difference between S and $. Meanwhile people will try and meet the requirements in the simplest way possible, with something like p4S$word - and they all think they’re really clever because they used @ instead of a, which is not clever at all and all the good crackers know about literally every replacement scheme. A MUCH better scheme (known as “correct horse battery staple”) is to have the user select four random words (there are services for this, but they tend to use a reduced word set - just flick through a dictionary, or get a word from the back of a shampoo bottle or something):

glossy lock pillar stinky


VASTLY easier to remember, and VASTLY harder to crack.

See the XKCD comic that introduced it:

https://www.xkcd.com/936/
And what do you think about KeePass password generator actually? Is that going to be in your opinion not safe as well, because "all the good crackers" are going to know the basics of character generator algorithm behind it?
Reply
#10

Quote:
Originally Posted by Riddick94
View Post
And what do you think about KeePass password generator actually? Is that going to be in your opinion not safe as well, because "all the good crackers" are going to know the basics of character generator algorithm behind it?
The thing that makes password managers good to use is that they provide long passwords. No matter what symbols are used, longer passwords are harder to brute force than shorter ones.
Reply
#11

As long as the user does not distributes his password to other users for his/her own safety and hashing algorithms can be found tons there day's

-Bcrypt
-SHA1
-SHA256
-SHA512
-Whirlpool

i know there types so far that depends how you hash your passwords in game is simple in a profession way to understand it on the other hand especialy for websites forum etc if the database is encrypted by outside (er's) there mite me a slightly hard way to de-crypt, there problems has been solved way back but hacks can be constantly seeking for what they desire more problems accure everyday only time depends wen problems can be solved in everyway its just my opinion
Reply
#12

tbh all u need to know these days is how to download bcrypt and implement it into your project. bcrypt handles everything u need it to and u dont have to worry about salting or anything like that
Reply
#13

I thought a little more on the correct horse battery staple method to choose passwords, but actually I just realized that there is a major problem.
Yes, because of its length, it is actually much harder to brute-force, but it contains known words. This actually means that if the attacker knows that the user is using this method, he could instead attempt with a dictionary attack.
Reply
#14

Quote:
Originally Posted by Y_Less
View Post
Please tell me how to use that with SA-MP. You’re right they’re better, but irrelevant here.



Not really, no.

If the attacker knows they are using that method, then this is more like a 4 character password, where each character is a dictionary word. That sounds worse, but is actually better.

A 10 normal character password has about 64 options for each character, that’s 64^10 possibilities, or 1.1529215e+18 combinations - quite a lot assuming people don’t use common combinations.

A 4 word password has about 175,000 options for each character, that’s 9.3789063e+20 combinations, 2 orders of magnitude harder, and only assuming English common words - mix in other languages and unusual words and you’re even better. Or simply add a fifth word and suddenly you have 1.6413086e+26.

Edit: The comic literally said all this.
That is true, but if the user used words which are all related to each other, he made the attacker's work easier.
Reply
#15

Quote:
Originally Posted by [HLF]Southclaw
View Post
Correct Horse Battery Staple.
How can we programmatically ensure that the user did not use "My name is Carl" as a password?
Reply
#16

Quote:
Originally Posted by Sasino97
Посмотреть сообщение
That is true, but if the user used words which are all related to each other, he made the attacker’s work easier.
Again, not really. Unless you know how the words are related. And it is still VASTLY better than normal passwords where people do use the same ones over and over, and those common passwords are very well known and documented. The theoretical difficulty in cracking normal passwords assumes that “Df3()AsЈ” is just as common as “p4ssw0RD”. Do you think that’s the case? You’re arguing that this method is less secure because it has a theoretical attack, while totally ignoring the fact that the current method has a known attack.

Edit:

Quote:
Originally Posted by Sasino97
Посмотреть сообщение
How can we programmatically ensure that the user did not use "My name is Carl" as a password?
Why? Yes, passwords with semantic meaning are slightly worse, but still vastly better than most normal passwords.

Again:

You’re arguing that this method is less secure because it has a theoretical attack, while totally ignoring the fact that the current method has a known attack. Is it perfect? No. Is it better than the alternative (when a password manager isn't available? Yes!
Reply
#17

Quote:
Originally Posted by Y_Less
View Post
Again, not really. Unless you know how the words are related. And it is still VASTLY better than normal passwords where people do use the same ones over and over, and those common passwords are very well known and documented. The theoretical difficulty in cracking normal passwords assumes that “Df3()AsЈ” is just as common as “p4ssw0RD”. Do you think that’s the case? You’re arguing that this method is less secure because it has a theoretical attack, while totally ignoring the fact that the current method has a known attack.

Edit:



Why? Yes, passwords with semantic meaning are slightly worse, but still vastly better than most normal passwords.

Again:

You’re arguing that this method is less secure because it has a theoretical attack, while totally ignoring the fact that the current method has a known attack. Is it perfect? No. Is it better than the alternative (when a password manager isn't available? Yes!
Sorry for my bad choice of words, I was not arguing that it is less secure than the common method, I was just trying to say that it is not the safest, for example a string like "1o3junr4eounjjaaa420asdmf21mno21r90sd9Lmjsaf2104k SPADPjfesoafa90sa90dfas" would be at the same time long enough to destroy any brute-force attack, random enough not to appear in any dictionary, but the downside is that it is almost impossible to memorize, and painful to type every time. When we have a password manager, then it is not a problem, but since for SA-MP it is not possible to implement it, then it is much better to use the correct horse method than using "p4$$word".
Reply
#18

Quote:
Originally Posted by Y_Less
View Post
Please tell me how to use that with SA-MP. You’re right they’re better, but irrelevant here.

[...]
I was pointing out something different. The password strength. If it is too complicated for people to create a strong password and make it easier to memorize, then why the hell not ALT-TAB out of the game, run KeePass, generate new entry with password, copy it and paste it back in the game? That's definetely going to be some quality password.

The advantage of it is to store all the passwords in one place if you are a KeePass user, but the kdb(x) file of the KeePass software is protected mainly with single password, which you actually should memorize somehow... or we could go even deeper with VeraCrypt softs etc. so that could be a long story.

I even remember my friend covering his monitor away from me, when he was typing in the password in SA-MP GUI when it didn't have the PASSWORD dialog definition back in the day. His pass. was about 5 chars. long.
Reply
#19

Quote:
Originally Posted by Sasino97
Посмотреть сообщение
How can we programmatically ensure that the user did not use "My name is Carl" as a password?
You don't have to allow the user to even submit a phrase, you can generate one using basic gramatical rules (adjective-noun-verb-noun for example).

Gfycat uses a similar method for generating URLs, for example "https://gfycat.com/gifs/detail/GrouchyAmbitiousAnura" - If I had to remember this URL, I simply visualise a grouchy ambitious anura, and I had no idea what an Anura was so I searched it and saw a picture, I'm not taking advantage of one of the most powerful elements of memory: visual. All of that combined plus a bit of repetition and this solution results in very easy to remember phrases.
Reply
#20

Actually, you should avoid grammar rules, just generate four random words in any order, otherwise you're restricting the combinations. Leave it to the user to invent/inject some meaning for memorisation.
Reply


Forum Jump:


Users browsing this thread: 3 Guest(s)