The project ‘Hasher’ is an open source .NET C# library which implements salted hashing.

You can use Hasher in your next account system to secure your sensitive data (e.g. user passwords).

Hasher implements salted hashing for killing dictionary attacks such as lookup tables, reverse lookup tables and rainbow tables.

Also, it uses keyed hashing. You can use various one-way keyed hashing algorithms such as :

  • MACTripleDES
  • HMACSHA512
  • HMACSHA384
  • HMACSHA256
  • HMACSHA1
  • HMACRIPEMD160
  • HMACMD5

Moreover, it supports key stretching for killing brute force attacks.

The key used in keyed hashing is generated by using key stretching previously.

Rfc2898DeriveBytes is used for key stretching which implements PBKDF2 (by using a pseudo-random number generator based on HMACSHA1).

A Cryptographically Secure Pseudo-Random Number Generator (RNGCryptoServiceProvider) is used for generating random salts.

The random salt is used both in keyed hashing and key stretching for securing both operations.

The comparison of the hashes is performed in O(1) time complexity for killing timing attacks.

The sensitive data is translated to UTF8 before hashing is performed.

Some more advantages of the Hasher are:

  • Security is configurable over time.
  • Parameters are configurable and do not break previously hashed information.

The parameters of the Hasher are:

  • Keyed one-way cryptography hashing algorithm
  • Iterations factor for rehashing text with salt (for generating the key)
  • The size of the key (used in keyed hashing)
  • The size of the salt (used both in key stretching and keyed hashing)

The size of the resulted hash it depends on the hash function.

The output of the Hasher is in this format: Algorithm : Iterations : Key Size : Salt : Hash

Both salt and hash are encoded in Base64 so you can store the output information in a database.

Small diagram for Hasher:

Hasher Diagram

Hasher Diagram

Example of using the Hasher:

public static void Main (string[] args)
{
    Hasher hasher = new Hasher ();

    hasher.Algorithm = "HMACSHA512";
    hasher.Iterations = 1000;
    hasher.SaltSize = 24;
    hasher.KeySize = 24;

    string secret1 = hasher.Create("secures");

    hasher.Algorithm = "HMACSHA256";
    hasher.Iterations = 2000;
    hasher.SaltSize = 32;
    hasher.KeySize = 32;

    string secret2 = hasher.Create("injects");

    hasher.Algorithm = "HMACSHA1";
    hasher.Iterations = 3000;
    hasher.SaltSize = 48;
    hasher.KeySize = 48;

    string secret3 = hasher.Create("bananas");

    Console.WriteLine("Validation: {0}", hasher.Validate("secures", secret1));
    Console.WriteLine("Validation: {0}", hasher.Validate("injects", secret2));
    Console.WriteLine("Validation: {0}", hasher.Validate("bananas", secret3));
}