What is Salt?
  • In cryptography, the expression refers to adding random data to the input of a hash function to guarantee a unique output – the hash – even when the inputs are the same.
  • The unique hash produced by adding the salt can protect against different attack vectors, such as hash table attacks, while slowing down dictionary and brute-force offline attacks.
  • There are limitations in the protections that a salt can provide. If the attacker is hitting an online service with a credential stuffing attack, a subset of the brute force attack category, salts won’t help at all because the legitimate server is doing the salting + hashing.
  • Salt is random data that is used as an additional input to a one-way function that hashes data, or a password, or a passphrase.
  • In general case, A Salt is passed along with the password to the hash function to prevent a collision by uniquely identifying a user password, even if another user in the system has selected the same password.
  • You can also add salt to make it more difficult for an attacker to break into your system using a password hash matching strategy.
  • Adding salt to a password hash prevents an attacker from testing known dictionary words across the entire system.
General process to add Salt to the password hash
  • Step 1: Generate a random string and save it as Salt.
  • Step 2: Prefix or Suffix the random string to the password and created a Salted Password .
  • Step 3: Pass the Salted Password to the hash function and apply encryption to generate a Salted Hash Password.
  • Step 4: Save the Salt from step 1 and Salted Hash Password from step 3 into the database.
Note

  • Every salt should be uniquely built and Prefixed or Suffixed with the password.
  • Salts should be saved with Salted Hash Password without any encryption applied to it.
  • A salt should be regenerated while the user password is changed.

General process to check Salted Hash Password
  • Step 1: Fetch the saved Salt and Salted Hash Password from the database.
  • Step 2: Prefix or Suffix the Salt with password and created a Salted Password.
  • Step 3: Pass the Salted Password to the hash function and apply the same encryption used while generating the Salted hash password previously.
  • Step 4: Compare the Salted Hash Password from step 1 and step 3, if they are equal then Grant Access to the user, else Deny Access.
Description of Argon2

  • Argon2 is a password-hashing function that summarizes the state of the art in the design of memory-hard functions and can be used to hash passwords for credential storage, key derivation, or other applications.

  • It has a simple design aimed at the highest memory filling rate and effective use of multiple computing units, while still providing defense against tradeoff attacks (by exploiting the cache and memory organization of the recent processors).

  • Argon2 has three variants: Argon2i, Argon2d, and Argon2id.

    • Argon2d is faster and uses data-depending memory access, which makes it highly resistant against GPU cracking attacks and suitable for applications with no threats from side-channel timing attacks (eg. cryptocurrencies).

    • Argon2i instead uses data-independent memory access, which is preferred for password hashing and password-based key derivation, but it is slower as it makes more passes over the memory to protect from tradeoff attacks.

    • Argon2id is a hybrid of Argon2i and Argon2d, using a combination of data-depending and data-independent memory accesses, which gives some of Argon2i’s resistance to side-channel cache timing attacks and much of Argon2d’s resistance to GPU cracking attacks.

    • Please Visit for more information.

Adding Salt to Password C# implementation using Argon2 ( Winner of PHC )
  • Steps to add and use Argon2 in your CSharpprojects for encrypting passwords with Salt.
    1. Add Dependencies to your Project by one of the following ways:
      • Package Manager: Install-Package Konscious.Security.Cryptography.Argon2 -Version 1.2.1
      • .NET CLI: dotnet add package Konscious.Security.Cryptography.Argon2 –version 1.2.1
      • Package Reference: “<"PackageReference Include="Konscious.Security.Cryptography.Argon2" Version="1.2.1" />
    2. Add the Library to your Project.

    3. using Konscious.Security.Cryptography;

    4. Generate a random Salt.

    5. public byte[] CreateSalt()
      						{
      							var buffer = new byte[32]; // Can be any random number mostly preferred more than 16
      							var rng = new RNGCryptoServiceProvider();
      							rng.GetBytes(buffer);
      							return buffer;
      						}
      					

    6. Generate HashPassword with added random Salt.

    7. public byte[] HashPassword(string password, byte[] salt)
      						{
      							var argon2 = new Argon2id(Encoding.UTF8.GetBytes(password));
      
      							argon2.Salt = salt;
      							argon2.DegreeOfParallelism = 8; // four cores
      							argon2.Iterations = 4;
      							argon2.MemorySize = 1024 * 1024; // 1 GB
      
      							return argon2.GetBytes(32); // Preferred same as the buffer size.
      						}
      					

    8. Optional process to verify HashPassword.

    9. public bool VerifyHash(string password, byte[] salt, byte[] hash)
      						{
      							var newHash = HashPassword(password, salt);
      							return hash.SequenceEqual(newHash);
      						}
      					

    10. Optional process to check the Hashing and Salting.

    11. static void Main(string[] args)
      						{
      							var password = "Pa$$w0rd ";
      							var stopwatch = Stopwatch.StartNew();
      
      							hashingPasswordWithSalt HashingPasswordWithSalt = new hashingPasswordWithSalt();
      
      							WriteLine($"Creating hash for password '{ password }'. ");
      
      							var salt = HashingPasswordWithSalt.CreateSalt();
      							WriteLine($"Using salt '{ Convert.ToBase64String(salt) }'. ");
      
      							var hash = HashingPasswordWithSalt.HashPassword(password, salt);
      							WriteLine($"Hash is '{ Convert.ToBase64String(hash) }'. ");
      
      							stopwatch.Stop();
      							WriteLine($"Process took { stopwatch.ElapsedMilliseconds / 1024.0 } s ");
      
      							stopwatch = Stopwatch.StartNew();
      							WriteLine($"Verifying hash... ");
      
      							var success = HashingPasswordWithSalt.VerifyHash(password, salt, hash);
      							WriteLine(success ? "Success...! " : "Failure...! ");
      
      							stopwatch.Stop();
      							WriteLine($"Process took { stopwatch.ElapsedMilliseconds / 1024.0 } s ");
      						}
      					

    12. Results

    13. 						/* Creating hash for password */ 'Pa$$w0rd'.
      
      						/* Using salt */ 'H2Ug5zZNN+dKTx7vantJEOp2euHJJwTizYUVPAKBcTw='.
      
      						/* Hash is */ 'kAulFna902q5Q0sQty9PaGiMoVO9eKvf3tHebtd9uh4='.
      
      						/* Process took */ 3.595703125 s
      
      						/* Verifying hash... */
      
      						/* Success...! */
      
      						/* Process took */ 3.4736328125 s
      					

Team Triveni (Technical)