SA-MP Forums

Go Back   SA-MP Forums > SA-MP Scripting and Plugins > Scripting Help > Tutorials

Reply
 
Thread Tools Display Modes
Old 12/07/2015, 10:12 AM   #1
dominik523
Gangsta
 
dominik523's Avatar
 
Join Date: Feb 2013
Location: Croatia
Posts: 891
Reputation: 115
Default Using new SHA-256 function

Introduction

Hey there! This will be a small tutorial about how to create salted passwords which will be hashed with the new SHA-256 hashing function.
First of, what is hashing?
Hash algorithms are one way functions. They turn any amount of data into a fixed-length "fingerprint" that cannot be reversed. They also have the property that if the input changes by even a tiny bit, the resulting hash is completely different (see the example below). This is great for protecting passwords, because we want to store passwords in a form that protects them even if the password file itself is compromised, but at the same time, we need to be able to verify that a user's password is correct.
Example of a hash:
Code:
hash("hello") = 2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824
hash("hbllo") = 58756879c05c68dfac9866712fad6a93f8146f337a69afe7dd238f3364946366
hash("waltz") = c0e81794384491161f1777c232bc6bd9ec38f616560b120fda8e90f383853542
Good way is to use a hash functions that can't be decrypted. But that's a naive way of storing passwords.
Better way is to add a salt to a password. A salt is an array of characters which is added to the password before the hash so it gets harder for people to crack the password by using brute force or dictionary attacks.
If you ever wondered how those attacks look like, here's a small example:
Code:
Dictionary Attack

Trying apple        : failed
Trying blueberry    : failed
Trying justinbeiber : failed
...
Trying letmein      : failed
Trying s3cr3t       : success!
Code:
Brute Force Attack

Trying aaaa : failed
Trying aaab : failed
Trying aaac : failed
...
Trying acdb : failed
Trying acdc : success!
Sorry if this is too long, but I think everyone who is dealing with passwords should know these things.
SHA-256

SHA-256 is a hash function that comes from SHA-2, set of hash functions designed by the NSA. It's a widely used in the Linux systems and some other security applications and protocols like TSL and SSL.
Let's write some code

In this tutorial, I'll show you how to make a code which will generate a random salt which will be added to our passwords later on. I'll show examples of storing the data in MySQL but you can use y_ini or some othes data saving system. It really doesn't matter.
So to start our code, I'm going to show you how to create a salt which will be inserted in our database along with password and other data.
Code:
enum pInfo
{
	pName[MAX_PLAYER_NAME],
	pPassword[65] // SHA-256 creates a hash of 64 characters,
	pSalt[11]
};

new PlayerInfo[MAX_PLAYERS][pInfo];

public OnDialogResponse(playerid, dialogid, response, listitem, inputtext[])
{
	if(dialogid == REGISTER_USER)
	{
		new salt[11];
		// generating random string of characters which is 10 character long
		for(new i; i < 10; i++)
		{
			// storing random character in every slot of our salt array
			salt[i] = random(79) + 47;
		}
		salt[10] = 0;
		SHA256_PassHash(inputtext, salt, PlayerInfo[playerid][pPassword], 65);
		// inputtext - text that we've entered in the dialog
		// query to save our name, password and salt
		new query[256];
		mysql_format(mysql, query, sizeof(query), "INSERT INTO `users` (`Name`, `Password`, `Salt`) VALUES ('%e', '%e', '%e')", PlayerInfo[playerid][pName], PlayerInfo[playerid][pPassword], salt);
  		mysql_tquery(mysql, query, "", "");
	}
	return 1;
}
This code will give us random generated salt which will be saved into the database as a plain-text, next to the password field.

salt[i] = random(79) + 47; - we are getting a random value from the ASCII table from 33 to 126, our you could say, we are getting one by one random generated character. After the salt is generated, we are adding a null value to the end of it.

Our users can now register at our server but they can't login yet. Here's the code for it:
Code:
public OnPlayerConnect(playerid)
{
    // checking for user in the database
	new query[128];
	mysql_format(mysql, query, sizeof(query),"SELECT `Password`, `Salt` FROM `users` WHERE `Name` = '%e'", PlayerInfo[playerid][pName]);
    mysql_tquery(mysql, query, "OnAccountCheck", "i", playerid);
	return 1;
}

forward public OnAccountCheck(playerid);

public OnAccountCheck(playerid)
{
	// if the users exists
    if(cache_get_row_count(mysql))
    {
        // saving password and salt from the database
        cache_get_field_content(0, "Password", PlayerInfo[playerid][pPassword], mysql, 65);
        cache_get_field_content(0, "Salt", PlayerInfo[playerid][pSalt], mysql, 11);
        // login dialog
		ShowDialog(playerid, LOGIN_USER);
    }
    else
    {
        // user doesn't exist, show the register dialog
        ShowDialog(playerid, REGISTER_USER);
    }
    return 1;
}

public OnDialogResponse(playerid, dialogid, response, listitem, inputtext[])
{
	// ...
	else if(dialogid == LOGIN_USER)
	{
	    new hash[65];
	    // hashing the text that user entered and salt that was loaded
        SHA256_PassHash(inputtext, PlayerInfo[playerid][pSalt], hash, 64);
        // if the hash is same as the loaded password
		if(!strcmp(hash, PlayerInfo[playerid][pPassword]))
  		{
    		// load user
    	}
		else
  		{
			// wrong password, show the dialog again etc.
    	}
	}
	return 1;
}
That's it! You should now have a more secure password saving system.
This is how it looks like in my database:

Some of the wrong ways of salting
  • Do not reuse salts (using same salt over multiple passwords)
    Code:
    A common mistake is to use same salt for hashing your passwords. This is ineffective because
    if two users have the same password, they'll still have the same hash. A new random salt must be 
    generated each time a user creates an account or changes their password.
    Oh, and don't use user's name for the salt since it's predictable and often reused for accounts 
    on other services.
  • Do not create short salts
    Code:
    If the salt is only three ASCII characters, there are only 95x95x95 = 857,375 possible salts. 
    To make it impossible for an attacker to create a lookup table for every possible salt, the salt 
    must be long. A good rule of thumb is to use a salt that is the same size as the output of the hash 
    function.
  • Do not do double hashing
    Code:
    It's easy to get carried away and try to combine different hash functions, hoping that the result 
    will be more secure. In practice, though, there is very little benefit to doing it. All it does is 
    create interoperability problems, and can sometimes even make the hashes less secure.
  • Do not use wacky hash functions
    Code:
    Never try to invent your own crypto, always use a standard that has been designed by experts.
Thank you for reading this tutorial. If you have some advices for better password managing, feel free to write them here.

Thanks to:
-CrackStation for making awesome article on secure salted password. You can find it here:
https://crackstation.net/hashing-sec...#normalhashing
- SA:MP team for adding SHA-256 hashing function alongside with many other useful stuf.
dominik523 is offline   Reply With Quote
Old 12/07/2015, 11:32 AM   #2
lukewid
Little Clucker
 
Join Date: Mar 2015
Posts: 35
Reputation: 0
Default Re: Using new SHA-256 function

Very nice!
lukewid is offline   Reply With Quote
Old 13/07/2015, 02:27 AM   #3
lexjusto
Little Clucker
 
lexjusto's Avatar
 
Join Date: May 2015
Location: Moscow, Russia
Posts: 8
Reputation: 1
Default Re: Using new SHA-256 function

good job.
lexjusto is offline   Reply With Quote
Old 13/07/2015, 05:53 AM   #4
dominik523
Gangsta
 
dominik523's Avatar
 
Join Date: Feb 2013
Location: Croatia
Posts: 891
Reputation: 115
Default Re: Using new SHA-256 function

Thank you guys.
__________________
[Tutorial] Using new SHA-256 function
dominik523 is offline   Reply With Quote
Old 13/07/2015, 08:14 AM   #5
zT KiNgKoNg
Gangsta
 
Join Date: Jun 2012
Location: $Location = $this->Location->Finder('United Kingdom');
Posts: 984
Reputation: 37
Default Re: Using new SHA-256 function

Its Ironic really; I was talking to someone when the update came out how SHA-256 can still be cracked, and anyone's best bet is to 'SALT' it, so Dominik, you sir have got yourself some rep just for doing this. GJ.
zT KiNgKoNg is offline   Reply With Quote
Old 13/07/2015, 08:37 AM   #6
dominik523
Gangsta
 
dominik523's Avatar
 
Join Date: Feb 2013
Location: Croatia
Posts: 891
Reputation: 115
Default Re: Using new SHA-256 function

Quote:
Originally Posted by zT KiNgKoNg View Post
Its Ironic really; I was talking to someone when the update came out how SHA-256 can still be cracked, and anyone's best bet is to 'SALT' it, so Dominik, you sir have got yourself some rep just for doing this. GJ.
Thank you very much.
I think it's a good thing that we got a new function so we don't have to use other plugins just for password security. I'm also glad to see that salting is supported by the function so we don't have to go and concatenate strings and do other stuff.
__________________
[Tutorial] Using new SHA-256 function
dominik523 is offline   Reply With Quote
Old 13/07/2015, 01:44 PM   #7
Lordzy
High-roller
 
Join Date: Mar 2012
Location: NetherRealm
Posts: 2,765
Reputation: 1172
Default Re: Using new SHA-256 function

It's good to see someone post a decent hashing tutorial with salting method. I suggest you to also note about updating salts at a particular time. In case if MySQL is used, event scheduler method can be handy!
Lordzy is offline   Reply With Quote
Old 13/07/2015, 05:25 PM   #8
dominik523
Gangsta
 
dominik523's Avatar
 
Join Date: Feb 2013
Location: Croatia
Posts: 891
Reputation: 115
Default Re: Using new SHA-256 function

Thanks for sharing that tutorial. It's nice to see some new cool stuff.
I haven't seen any tips on updating the salt over time but it might be useful.
__________________
[Tutorial] Using new SHA-256 function
dominik523 is offline   Reply With Quote
Old 13/07/2015, 11:53 PM   #9
Youssef221
Big Clucker
 
Join Date: Jul 2013
Posts: 194
Reputation: 11
Default Re: Using new SHA-256 function

Wish you could explain it in Yini, but good job.
Youssef221 is offline   Reply With Quote
Old 14/07/2015, 12:06 AM   #10
zT KiNgKoNg
Gangsta
 
Join Date: Jun 2012
Location: $Location = $this->Location->Finder('United Kingdom');
Posts: 984
Reputation: 37
Default Re: Using new SHA-256 function

Quote:
Originally Posted by Youssef221 View Post
Wish you could explain it in Yini, but good job.
Pretty much the same to be honest, just INI functions.
zT KiNgKoNg is offline   Reply With Quote
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Error 055: start of function body without function header Magnezia Scripting Help 3 19/05/2015 05:11 AM
[Ajuda] error 055: start of function body without function header AndersonAq PortuguÍs/Portuguese 3 14/03/2014 12:31 AM
Returning inside a switch case, does it go back to the scope of the function, or does it return for the function? Hoborific Scripting Help 4 26/06/2013 12:47 PM


All times are GMT. The time now is 11:27 AM.


Powered by vBulletin® Version 3.8.6
Copyright ©2000 - 2018, Jelsoft Enterprises Ltd.