czwartek, 6 grudnia 2012

Secure password storage

Recently I've seen a post of someone being really supprised, that his site was hacked. He was aware that his site is prone to SQL-Injection, but he couldn't understand how it could lead to a successful login.
His passwords was SHA-256 hashed. Was it possible for attacker to reverse actual password ? Unlikely... all the needed to do is to write a union select:

select username, password from users where username = '-1'
union select 'admin','8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918' from dual;

password is hashed 'admin' string, and he was able to trick authentication
checking logic, by providing 'admin' in password string. Simple right ? So I started wondering is there a way to hash passwords in a way that would withstand such attack (of course if your app is prone to SQL-Injection you fix IT! not leave it and wish for the best). And I there is a way.

The algorithm for hash creation could be something like:
  1. Define a cryptographically secure hash function like: sha256
  2. Define web application global secure random password, lets denote it: key
  3. Get username credentials (username, password).
  4. Create a salt := sha256(username + secure_random)
  5. Calculate hash:= sha256(salt + password + key)
  6. Store salt+hash in database.

And now the checking algorithm:

  1. Lookup (salt+hash) tuple for given username.
  2. Calculate provided_hash:= sha256(salt + provided_password + key)
  3.  Compare provided_hash with hash
  4. If they match your user can be authenticated
Why is this scheme more secure? It's simple, even if attacker can extract stored salt, or if he knows the length of stored salt he can try to fake it. He will not have access to your secret key, thus he won't be able to calculate a valid hash.

P.S.: SHA can be replaced by some KDF function like PBKDF2 or scrypt.

Brak komentarzy:

Prześlij komentarz