• 2 Vote(s) - 5 Average
  • 1
  • 2
  • 3
  • 4
  • 5
A Proper Way to Store Passwords
#1
Passwords



A Proper Way to Store Passwords



By Sasinosoft



This is an edited version of my SA-MP forums?article about storing passwords the most secure way.



Introduction

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,?in the case of San Andreas Multiplayer, that?"it is just a game", so the security of the game accounts is not to be taken?seriously. However, a poll showed that?59%?of people use the same password everywhere or almost everywhere.?[source]?



If the attacker gets access to your game data base, he will most likely obtain all your users' nicknames and passwords, and if they are not properly hashed, then congratulations:?you have just 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 Google, Microsoft, mail providers, using the passwords and user names he just stole, and this creates high security risks, including the possibility of stealing payment information.



Here you?are a few tips?to make his work harder.





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 it is likely 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 also add that there are better algorithms than SHA-256, such as?bcrypt. On the Burgershot?forums you can find at least two?plugins for bcrypt [SyS's SampBcrypt]?[Bork's samp-crypto].



Do not simply hash the password and store it

Why? Just hashing the password and storing it,?adds 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, thus reducing his intentions to get the passwords,?you must?put salt on them.



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 not intended to be?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.





Do not use usernames 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 likely focus on this particular user.?



Also, if you implemented a system to let the user change his password, you would?then going to hash it with the same salt as before:?you usually want to avoid this.

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.





Avoid writing your own hashing algorithm



While it may seem a good idea to write your own algorithm so that there are no pre-made attacks against it, it's not. Real motivated hackers will simply analyze it and then they will?crack it. 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.



Use bcrypt

[Image: http:]



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 [SyS's SampBcrypt]?[Bork's samp-crypto].

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.

Among the?advantages, I have to mention that?bcrypt?will generate the salt for you and put it in the same string as the hash, so you will just need one data base?column.

We hope that the open.mp team will implement native?support for bcrypt in the API.



Bonus 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
Absolutely brilliant tutorial.



This is very well written and explained, you clearly done your homework :)



I'm glad tutorials like this exist, I will be making this topic sticky, as it's a common issue most servers fail to implement.
Remember to always refer to J0sh as `J0sh...`



@ Networks/Servers

San Andreas Gaming Network (Owner/Founder)

San Andreas Gaming (Owner/Founder)

Grand Theft Cop's n Robber's (Owner)

Britannia Roleplay (Owner/Founder) [Retired]

Alpine RP (Owner/Founder)

Aluminium Network (Maintainer) [Disbanded]

AlphaDM (Tech Support) [Disbanded]



# Services

forum.open.mp (Forum Manager) (Formerly Burgershot.gg

open.mp (Member)



~ Languages/Frameworks

Pawn, C, C, C#, Javascript, Typescript, Lua, Python, Go, Rust, PHP, SQL,

Angular, React, Vue, Svelte, Laravel, Rocket
  Reply
#3
Is forcing the attacker to go for a brute-force option the only reason why salts are used?
  Reply
#4
Quote:If any website emails your password back in plain text, then he is surely storing your password as such

Not really.?You can't know that. You could just hash a temporary plain password, save it in the database, and send the plain pass to the user
[Image: GitHub-michaelbelgium-000000.svg?style=for-the-badge]

  Reply
#5
(2019-04-30, 07:05 PM)michael@belgium Wrote:
Quote:If any website emails your password back in plain text, then he is surely storing your password as such



Not really.?You can't know that. You could just hash a temporary plain password, save it in the database, and send the plain pass to the user



I think the key word there is "your". It is perfectly fine to send a random temporary password, not the user's original password.
  Reply
#6
(2019-04-30, 05:42 PM)anesthesia Wrote: Is forcing the attacker to go for a brute-force option the only reason why salts are used?



Salts prevent dictionary attacks and rainbow tables.
  Reply
#7
And it means you need to crack every password separately. Without a salt two identical passwords would hash to the same thing.
  Reply
#8
Been peppering passwords since always xd good tutorial btw. 10/10.
  Reply
#9
Nice!
  Reply
#10
Hello, thank you for all your replies, I appreciate it. If you have any suggestion to



(2019-04-30, 07:05 PM)michael@belgium Wrote:
Quote:If any website emails your password back in plain text, then he is surely storing your password as such



Not really.?You can't know that. You could just hash a temporary plain password, save it in the database, and send the plain pass to the user



You are right because it is possible that they are emailing it from memory and not from the DB, I will?change 'surely' with 'likely' (also 'he' with 'it').
  Reply
#11
(2019-04-30, 07:05 PM)michael@belgium Wrote:
Quote:If any website emails your password back in plain text, then he is surely storing your password as such



Not really.?You can't know that. You could just hash a temporary plain password, save it in the database, and send the plain pass to the user



That's still a terrible red flag. Password hashing shouldn't be reversible. And there should be no plaintext passwords anywhere for absolutely no reason (other than in memory when a log-in or register is being executed, in which case it must be properly trashed inmediatly after the operaton is complete)
  Reply
#12
Great Tutorial champ, lots of people should take a read at it, it was pretty useful for me too. thanks for sharing this with us
  Reply


Forum Jump: