SA-MP Forums Archive
[Plugin] Hash Plugin [PBKDF2, CSPRNG, SHA, Whirlpool, RIPEMD, Checksums and more] - Printable Version

+- SA-MP Forums Archive (https://sampforum.blast.hk)
+-- Forum: SA-MP Scripting and Plugins (https://sampforum.blast.hk/forumdisplay.php?fid=8)
+--- Forum: Plugin Development (https://sampforum.blast.hk/forumdisplay.php?fid=18)
+--- Thread: [Plugin] Hash Plugin [PBKDF2, CSPRNG, SHA, Whirlpool, RIPEMD, Checksums and more] (/showthread.php?tid=496953)



Hash Plugin [PBKDF2, CSPRNG, SHA, Whirlpool, RIPEMD, Checksums and more] - Mellnik - 24.02.2014

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 Код:
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 Код:
native random_int(min, max); // Also works with negative values.
native random_string(length, output[], len = sizeof(output));
Non-cryptographic algorithms
pawn Код:
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 Код:
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 Код:
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 Код:
native slow_equals(const a[], const b[]);
Hash output length
Always add +1 for the null terminator.
pawn Код:
#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 Код:
#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;
}
Password hashing with salts
pawn Код:
#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
Код:
plugins hash.so
Windows
Код:
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
Код:
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
Код:
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


Re: Hash Plugin [PBKDF2, CSPRNG, SHA, Whirlpool, RIPEMD, Checksums and more] - d711728 - 24.02.2014

Nice Job!


Re: Hash Plugin [PBKDF2, CSPRNG, SHA, Whirlpool, RIPEMD, Checksums and more] - Guest4390857394857 - 24.02.2014

well done!!!


Re: Hash Plugin [PBKDF2, CSPRNG, SHA, Whirlpool, RIPEMD, Checksums and more] - Kyle - 24.02.2014

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.


Re: Hash Plugin [PBKDF2, CSPRNG, SHA, Whirlpool, RIPEMD, Checksums and more] - iZN - 24.02.2014

This is indeed useful and good work, Mellnik!


Re: Hash Plugin [PBKDF2, CSPRNG, SHA, Whirlpool, RIPEMD, Checksums and more] - QuaTTrO - 24.02.2014

AWWWWWWWWWWWWW YISS.

I was waiting for this all in one plugin. GREAT JOB!


Re: Hash Plugin [PBKDF2, CSPRNG, SHA, Whirlpool, RIPEMD, Checksums and more] - Alex Magaсa - 24.02.2014

nice job!


Re: Hash Plugin [PBKDF2, CSPRNG, SHA, Whirlpool, RIPEMD, Checksums and more] - shittt - 25.02.2014

g00d job , that's what I wanted .


Re: Hash Plugin [PBKDF2, CSPRNG, SHA, Whirlpool, RIPEMD, Checksums and more] - GShock - 22.03.2014

Nice!! Well done Mell!


Re: Hash Plugin [PBKDF2, CSPRNG, SHA, Whirlpool, RIPEMD, Checksums and more] - GiamPy. - 22.03.2014

Please add a decent bcrypt implementation.