Conrad Ludgate
Conrad Ludgate

Reputation: 11

Hashing and Salting confusion

I have read a lot about hashing and salting passwords. I know how hashing works, that is all very easy, but the thing I am confused about is salting.

If I hash and salt a password and stick it into the database, how can I check that password with the password given when a user tries to log-in. Surely because the salt is completely random, it will be near-impossible to get that salt again to be able to match the database

EXAMPLE:

//On create account.
hash(password + randomSalt) to the Database

//On log-in
hash(password + differentRandomSalt) compare to Database

Upvotes: 1

Views: 240

Answers (2)

Jan Köhler
Jan Köhler

Reputation: 6020

You generate a random hash of a fixed length with every password you hash. Then you store that salt in combination with the computed hash into one database column.

When the user wants to login, you extract the salt-part from the database and can match the results.

Example:

var salt = GenerateSecureRandom(16) // generates e.g. 0x42552241
var saltedHash = Hash(salt + password)

Login scenario:

var saltedHash = GetSaltedHashFromDatabase()
var salt = GetFirstBytes(saltedHash)     // 0x42552241
var hash = GetRemainingBytes(saltedHash) // 0x47111337
var match = IsMatch(hash, salt, userInput)

A database entry could look like this (where = is the salt and * is the hash):

0x4255224147111337
  ========********

For (much) more details have a look at: https://crackstation.net/hashing-security.htm

Upvotes: 2

Maarten Bodewes
Maarten Bodewes

Reputation: 93938

The salt is random for each different user/password combination. It's not random for the same user/password combination. If that would be the case, then you would not be able to verify the password, as you already found out. If a large enough salt is generated with a sufficiently secure random number generator then it would even be impossible to verify the password. The idea of the salt is to protect against rainbow table attacks as well as creating a different password hash for different users if the password is the same.

The salt is usually stored together with the username and password hash in the database. It could be made part of a special construct that contains the salt and the password hash or it could be stored in a separate column. Sometimes the password-hash is actually a special string containing both the salt and the hash in some kind of format (using hexadecimal or base64 encoding) that needs to be parsed, but it could also a binary value simply consisting of a statically sized salt and statically sized hash.

An example bcrypt string would be:

$2a$12$QyrjMQfjgGIb4ymtdKQXIewDBqhA3eNppF8qOrMhidnEbzNvmHqhy

which is constructed as in this SO answer.

Setup:

  1. find user
  2. receive & verify old + password (see below)
  3. receive new password
  4. generate random salt
  5. calculate hash from password and salt
  6. store salt & hash in database with user

Verification:

  1. find user
  2. receive password
  3. retrieve salt & hash for user
  4. calculate hash to verify from password and salt
  5. compare and return result

Usually, for security reasons, you should try and do a time-constant compare, even if that's not really an issue for password hashing. Furthermore often no distinction is made between unknown user and wrong password, simply to avoid giving information to attackers.

It makes sense to construct your password hashing scheme in such a way that it allows for updates to the amount of iterations, hash size, hash function etc.

Upvotes: 1

Related Questions