[Tutorial] Using new SHA-256 function
#1

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:
pawn 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.
pawn 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:
pawn 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.
Reply


Messages In This Thread
Using new SHA-256 function - by dominik523 - 12.07.2015, 10:12
Re: Using new SHA-256 function - by lukewid - 12.07.2015, 11:32
Re: Using new SHA-256 function - by lexjusto - 13.07.2015, 02:27
Re: Using new SHA-256 function - by dominik523 - 13.07.2015, 05:53
Re: Using new SHA-256 function - by zT KiNgKoNg - 13.07.2015, 08:14
Re: Using new SHA-256 function - by dominik523 - 13.07.2015, 08:37
Re: Using new SHA-256 function - by Lordzy - 13.07.2015, 13:44
Re: Using new SHA-256 function - by dominik523 - 13.07.2015, 17:25
Re: Using new SHA-256 function - by Youssef221 - 13.07.2015, 23:53
Re: Using new SHA-256 function - by zT KiNgKoNg - 14.07.2015, 00:06
Re: Using new SHA-256 function - by yugecin - 14.07.2015, 00:06
Re: Using new SHA-256 function - by scaunel - 14.07.2015, 01:10
Re: Using new SHA-256 function - by dominik523 - 14.07.2015, 08:36
Re: Using new SHA-256 function - by Hiddos - 14.07.2015, 10:59
Re: Using new SHA-256 function - by dominik523 - 14.07.2015, 11:58
Re: Using new SHA-256 function - by Youssef221 - 14.07.2015, 13:28
Re: Using new SHA-256 function - by Youssef221 - 14.07.2015, 16:41
Re: Using new SHA-256 function - by dominik523 - 14.07.2015, 17:08
Re: Using new SHA-256 function - by Cyber123 - 14.07.2015, 23:05
Re: Using new SHA-256 function - by RaeF - 16.07.2015, 03:12
Re: Using new SHA-256 function - by rymax99 - 16.07.2015, 03:48
Re: Using new SHA-256 function - by dominik523 - 16.07.2015, 07:46
Re: Using new SHA-256 function - by AchievementMaster360 - 20.07.2015, 20:04
Re: Using new SHA-256 function - by venomlivno8 - 15.01.2016, 09:45
Re: Using new SHA-256 function - by Vince - 15.01.2016, 17:50
Re: Using new SHA-256 function - by PrO.GameR - 18.08.2016, 20:49
Re: Using new SHA-256 function - by SKAzini - 18.08.2016, 21:36
Re: Using new SHA-256 function - by BugsBunny - 19.02.2017, 11:12
Respuesta: Using new SHA-256 function - by Juance - 28.02.2017, 12:39
Re: Using new SHA-256 function - by Phreak - 21.04.2018, 12:19
Re: Using new SHA-256 function - by ranme15 - 21.04.2018, 13:33
Re: Using new SHA-256 function - by JesterlJoker - 21.04.2018, 16:47
Re: Using new SHA-256 function - by AmigaBlizzard - 22.04.2018, 20:46
Re: Using new SHA-256 function - by JesterlJoker - 23.04.2018, 11:00
Re: Using new SHA-256 function - by iKarim - 23.04.2018, 16:11
Re: Using new SHA-256 function - by AmirSavand - 11.09.2018, 23:08

Forum Jump:


Users browsing this thread: 1 Guest(s)