SA-MP Forums

Go Back   SA-MP Forums > SA-MP Scripting and Plugins > Plugin Development

Reply
 
Thread Tools Display Modes
Old 24/02/2014, 04:26 PM   #1
Mellnik
Gangsta
 
Mellnik's Avatar
 
Join Date: Dec 2011
Location: Paradise Falls, CAℕADA
Posts: 796
Reputation: 369
Default Hash Plugin [PBKDF2, CSPRNG, SHA, Whirlpool, RIPEMD, Checksums and more]

Hash Plugin 0.0.3

This plugin was created to provide simple access to common hash function, CSPRNG and the PBKDF2 hashing method. There are, however, some other neat features listed below.
I have seen many gamemodes/scripts being released which do have a bad security when it comes to password handling. I think the problem is that people are not aware of how easy it is to crack the passwords e.g. using rainbow tables. A year ago I've released a script which uses MD5 for hashing passwords. When I look at it now, I see that this was the wrong way of doing it. This plugin will make it easy for you to securely handle passwords entrusted by your players.

Features
- PBKDF2, a secure way of handling passwords
- Pseudo Random Generators using /dev/random or CryptGenRandom() on Windows
- Hash algorithms: SHA256, SHA384, SHA512, SHA3 (Keccak-512), Whirlpool, RIPEMD160, RIPEMD256, RIPEMD320
- File checksums: MD5, SHA1, SHA256, SHA384, SHA512, Whirlpool
- Hex and base64 coding/decoding

Documentation

Hash functions
pawn Code:
native sha256(const key[], hash[], len = sizeof(hash));
native sha384(const key[], hash[], len = sizeof(hash));
native sha512(const key[], hash[], len = sizeof(hash));
native sha3(const key[], hash[], len = sizeof(hash));
native whirlpool(const key[], hash[], len = sizeof(hash));
native ripemd160(const key[], hash[], len = sizeof(hash));
native ripemd256(const key[], hash[], len = sizeof(hash));
native ripemd320(const key[], hash[], len = sizeof(hash));

Pseudo random generators
The output of these functions is cryptographically secure. Please scroll down to Notes for more information.
pawn Code:
native random_int(min, max); // Also works with negative values.
native random_string(length, output[], len = sizeof(output));

Non-cryptographic algorithms
pawn Code:
native base64_encode(const input[], output[], len = sizeof(output));
native base64_decode(const input[], output[], len = sizeof(output));
native hex_encode(const input[], output[], len = sizeof(output));
native hex_decode(const input[], output[], len = sizeof(output));

PBKDF2 Hashing
PBKDF2 is a key derivation function also known as "key stretching" this method provides a high level of security. Please scroll down for an example and more information.
pawn Code:
native hash_generate(const key[], iterations, const callback[], const format[], {Float,_}:...);
native hash_retrieve(hash[], salt[], hlen = sizeof(hash), slen = sizeof(salt));
native hash_validate(const key[], const hash[], const salt[], iterations, const callback[], const format[], {Float,_}:...);
native hash_is_equal();
native hash_unprocessed(); // Returns the internal number of unprocessed PBKDF2 workers.
native hash_exec_time(); // Returns the execution time in milliseconds.
native hash_thread_limit(threads); // Sets the number of worker threads.

File checksums
pawn Code:
native md5sum(const file[], sum[], len = sizeof(sum));
native sha1sum(const file[], sum[], len = sizeof(sum));
native sha256sum(const file[], sum[], len = sizeof(sum));
native sha384sum(const file[], sum[], len = sizeof(sum));
native sha512sum(const file[], sum[], len = sizeof(sum));
native wpsum(const file[], sum[], len = sizeof(sum));

Length-constant comparison
pawn Code:
native slow_equals(const a[], const b[]);

Hash output length
Always add +1 for the null terminator.
pawn Code:
#define PBKDF2_LENGTH 128
#define MD5_LENGTH 32
#define SHA1_LENGTH 40
#define SHA256_LENGTH 64
#define SHA384_LENGTH 96
#define SHA512_LENGTH 128
#define SHA3_LENGTH 128
#define WHIRLPOOL_LENGTH 128
#define RIPEMD160_LENGTH 40
#define RIPEMD256_LENGTH 64
#define RIPEMD320_LENGTH 80

Hashing passwords with PBKDF2
pawn Code:
#include <a_samp>
#include <hash>

#define ITERATIONS 150000

public OnDialogResponse(playerid, dialogid, response, listitem, inputtext[])
{
    switch(dialogid)
    {
        case DIALOG_REGISTER:
        {
            hash_generate(inputtext, ITERATIONS, "OnPasswordHash", "i", playerid);
            return 1;
        }
        case DIALOG_LOGIN:
        {
            new hash[PBKDF2_LENGTH + 1], salt[PBKDF2_LENGTH + 1];
            // The variable hash and salt are being fetched from database.
            hash_validate(inputtext, hash, salt, ITERATIONS, "OnPasswordValidate", "i", playerid);
            return 1;
        }
    }
    return 0;
}

forward public OnPasswordHash(playerid);
public OnPasswordHash(playerid)
{
    new hash[PBKDF2_LENGTH + 1], salt[PBKDF2_LENGTH + 1];
    hash_retrieve(hash, salt);
   
    SendClientMessage(playerid, 0xFFFFFFFF, "Your password has been hashed.");
    // You can now save hash and salt in the database.
    return 1;
}

forward public OnPasswordValidate(playerid);
public OnPasswordValidate(playerid)
{
    if(hash_is_equal())
    {
        SendClientMessage(playerid, 0xFFFFFFFF, "Correct password!");
    }
    else
    {
        SendClientMessage(playerid, 0xFFFFFFFF, "Invalid password!");
    }
    return 1;
}
  • PBKDF2 stands for Password-Based Key Derivation Function 2.
  • A cryptographically secure 512 bit salt is being generated internally and applied to the password.
  • The iteration count specifies how often the password is being hashed to generate a derived key (hash).
  • The Hash Plugin implemenation uses Whirlpool for hashing.
  • I recommend using 100000 iterations but this mostly depends on the CPU power you have available. The higher the iteration count the more difficult it is to crack the password.
  • It takes approximately 400ms to generate the derived key when using 100000 iterations.

Password hashing with salts
pawn Code:
#include <a_samp>
#include <hash>

public OnDialogResponse(playerid, dialogid, response, listitem, inputtext[])
{
    switch(dialogid)
    {
        case DIALOG_REGISTER:
        {
            new salt[33], string[128 + 33];
            random_string(32, salt);
           
            format(string, sizeof(string), "%s%s", inputtext, salt);
           
            new hash[SHA3_LENGTH + 1];
            sha3(string, hash);
           
            SCM(playerid, 0xFFFFFFFF, "Your password has been salted and hashed!");
            // Save salt and hash in the database.
            return 1;
        }
        case DIALOG_LOGIN:
        {
            new hash[SHA512_LENGTH + 1], salt[33];
            // The variable hash and salt are being fetched from database.
           
            new string[128 + 33], validate_hash[SHA3_LENGTH + 1];
            format(string, sizeof(string), "%s%s", inputtext, salt);
            sha3(string, validate_hash);
           
            if(!strcmp(hash, validate_hash))
            {
                SendClientMessage(playerid, 0xFFFFFFFF, "Correct password!");
            }
            else
            {
                SendClientMessage(playerid, 0xFFFFFFFF, "Invalid password!");
            }
            return 1;
        }
    }
    return 0;
}

Download & Changelog
(2018-09-07) 0.0.5 GitHub download
- Fix empty-string crash
- Add crc32 support
- Update Crypto++ to 7.0.0
- Rewrite to use C++17 standard
- Remove boost reference
- Add sampctl config by BronzeCheese

(2014-07-08 ) 0.0.4 GitHub download
- Security update

(2014-04-01) 0.0.3 hash-plugin-0.0.3.rar
- Crypto++ will now be compiled within the Hash Plugin rather than using a precompiled library
- Code improvements

Thanks to maddinat0r for his contribution.

(2014-03-27) 0.0.2 hash-plugin-0.0.2.rar
- Added SHA3() function using Keccak-512

(2014-02-24) 0.0.1 hash-plugin-0.0.1.rar
- Initial release

Installation
Add the include file (hash.inc) to your script and re-compile.
Upload the Hash Plugin in the plugin folder of your server and append following to the server.cfg.

Linux
Code:
plugins hash.so
Windows
Code:
plugins hash
Source Code & Compiling Notes
The full source code can be viewed on Github. In order to compile it you will need to install the boost library (Explained below).

Linux
Code:
NOTE: Boost is no longer required since version 0.0.5
Install gcc, g++ and make on your machine.
Download, extract boost and install boost:
# ./bootstrap.sh
# ./b2 address-model=32 variant=release install
Clone the Github project and find the directory which contains makefile.
Type make to start compiling.
After compiling hash.so will be located in the bin folder.
Windows
Code:
NOTE: Boost is no longer required since version 0.0.5
Download and extract boost.
Open a command line and navigate to the extracted folder.
> bootstrap
> b2 toolset=msvc-10.0 variant=release threading=multi link=static
Close the Github project and open it with Visual C++ 2010.
Select "Release" from the dropdown menu at the top.
Go to the solution property page -> VC++ Directories.
Point Include Directories and Library Directories to your boost installation folder.
Compile the project.
After compiling hash.dll will be located in the bin folder.
Notes
  • Unlike the pawn native "random", both random_int and random_string uses /dev/random or /dev/urandom on Linux and CryptGenRandom() on Windows. Those are not real random generated numbers but pseudo random generated numbers. This means that they still follow algorithms unlike humans do.
  • NEVER use base64 or hex to encode passwords! They can be decoded as are not made for that purpose. Please refer to Wikipedia if you want to learn more about base64 and hex.
  • You can generate salts using random_string. Do not reuse salts. The charset is 0-9, a-z and A-Z.
  • All hashes are being output in uppercase.
  • A test script can be found here: http://pastebin.com/7vC7DtZg
  • Please do not suggest MD5 or any other weak algorithm to be added as a hashing function.
  • I have tested the plugin under Windows 8, CentOS 6.5 and Ubuntu 10.04.
  • The Hash Plugin works because of the effort put into the Crypto++ and boost library. You might want to check out their sites.

Last edited by Mellnik; 07/02/2019 at 04:30 PM.
Mellnik is offline   Reply With Quote
Old 24/02/2014, 05:10 PM   #2
d711728
Big Clucker
 
d711728's Avatar
 
Join Date: Jun 2012
Posts: 92
Reputation: 0
Default Re: Hash Plugin [PBKDF2, CSPRNG, SHA, Whirlpool, RIPEMD, Checksums and more]

Nice Job!
d711728 is offline   Reply With Quote
Old 24/02/2014, 05:47 PM   #3
Guest4390857394857
Guest
 
Posts: n/a
Thumbs up Re: Hash Plugin [PBKDF2, CSPRNG, SHA, Whirlpool, RIPEMD, Checksums and more]

well done!!!
  Reply With Quote
Old 24/02/2014, 07:14 PM   #4
Kyle
High-roller
 
Kyle's Avatar
 
Join Date: Mar 2009
Location: United Kingdom
Posts: 2,388
Reputation: 319
Default Re: Hash Plugin [PBKDF2, CSPRNG, SHA, Whirlpool, RIPEMD, Checksums and more]

Some nice functions there, but I'm not sure it's worth loading the plugin for 1 or 2 uses. Not many people use several encryptions, usually they use the same one.
Kyle is offline   Reply With Quote
Old 24/02/2014, 07:17 PM   #5
iZN
High-roller
 
Join Date: Jun 2010
Posts: 2,441
Reputation: 569
Default Re: Hash Plugin [PBKDF2, CSPRNG, SHA, Whirlpool, RIPEMD, Checksums and more]

This is indeed useful and good work, Mellnik!
__________________
iZN is offline   Reply With Quote
Old 24/02/2014, 09:15 PM   #6
QuaTTrO
Gangsta
 
QuaTTrO's Avatar
 
Join Date: Aug 2009
Posts: 571
Reputation: 75
Default Re: Hash Plugin [PBKDF2, CSPRNG, SHA, Whirlpool, RIPEMD, Checksums and more]

AWWWWWWWWWWWWW YISS.

I was waiting for this all in one plugin. GREAT JOB!
QuaTTrO is online now   Reply With Quote
Old 24/02/2014, 09:36 PM   #7
Alex Magaņa
High-roller
 
Alex Magaņa's Avatar
 
Join Date: Oct 2012
Location: 𝕭𝖗𝖔𝖙𝖍𝖊𝖗𝖍𝖔𝖔𝖉
Posts: 2,466
Reputation: 216
Default Re: Hash Plugin [PBKDF2, CSPRNG, SHA, Whirlpool, RIPEMD, Checksums and more]

nice job!
__________________

HOME --- FORUMS --- DISCORD --- SERVER
Alex Magaņa is offline   Reply With Quote
Old 25/02/2014, 10:27 PM   #8
shittt
Gangsta
 
shittt's Avatar
 
Join Date: Apr 2013
Location: I came back
Posts: 796
Reputation: 78
Default Re: Hash Plugin [PBKDF2, CSPRNG, SHA, Whirlpool, RIPEMD, Checksums and more]

g00d job , that's what I wanted .
__________________
Hi
shittt is offline   Reply With Quote
Old 22/03/2014, 04:26 PM   #9
GShock
Big Clucker
 
GShock's Avatar
 
Join Date: Aug 2013
Location: 120.0.0.1
Posts: 130
Reputation: 22
Default Re: Hash Plugin [PBKDF2, CSPRNG, SHA, Whirlpool, RIPEMD, Checksums and more]

Nice!! Well done Mell!
__________________


FrequencyX
NEF Server
GShock is offline   Reply With Quote
Old 22/03/2014, 05:01 PM   #10
GiamPy.
Huge Clucker
 
GiamPy.'s Avatar
 
Join Date: Apr 2011
Location: Ravenna, Italy
Posts: 224
Reputation: 16
Default Re: Hash Plugin [PBKDF2, CSPRNG, SHA, Whirlpool, RIPEMD, Checksums and more]

Please add a decent bcrypt implementation.
GiamPy. 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
Whirlpool hash problem Face9000 Scripting Help 15 04/01/2014 11:24 PM
Whirlpool hash on login Jimmy0wns Scripting Help 2 01/01/2014 01:17 PM
Whirlpool HASH Stefand Scripting Help 3 06/12/2012 04:13 PM
Password hash issue (Whirlpool) sim_sima Scripting Help 8 14/03/2012 04:24 PM


All times are GMT. The time now is 01:02 PM.


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