Your Password Hashing Algorithm Is Bad And You Should Feel Bad

No

$pw = md5('password');
$pw = md5('salt' . 'password');
$pw = md5('complicated_salt' . 'password');
$pw = md5('complicated_salt' . strrev('password')); // Don't be clever.

Where md5() = sha1(), base64_encode(), etc.

This type of password hashing is still widespread and susceptible to rainbow table attacks.

Yes

$pw = password_hash('password', PASSWORD_DEFAULT);

(Source)

Uses bcrypt, this particular implementation auto-magically hardens itself over time.

How to use

You are responsible for new \Pdo(), $condition, maybe asking the user to make their 'password' not suck. Read the snippet and reason about it. Don’t just copy/paste, it won’t work.


// Save user password into database

$pw = password_hash($_REQUEST['pw'], PASSWORD_DEFAULT);
$stmt = $pdo->prepare('UPDATE users SET password=? WHERE condition=?');
$stmt->execute([$pw, $condition]);

// Verify user login

$stmt = $pdo->prepare('SELECT password FROM users WHERE condition=?'); 
$stmt->execute([$condition]); 
$row = $stmt->fetch();

if (password_verify($_REQUEST['pw'], $row['password'])) {
  // Check if PHP has improved password security for us
  if (password_needs_rehash($row['password'], PASSWORD_DEFAULT)) {
    // Fix password for next time
    $pw = password_hash($_REQUEST['pw'], PASSWORD_DEFAULT);
    $stmt = $pdo->prepare('UPDATE users SET password=? WHERE condition=?');
    $stmt->execute([$pw, $condition]);
  }
  // Log in
} else {
  // Invalid password
}

Keep on shaking that salt shaker.

3 thoughts on “Your Password Hashing Algorithm Is Bad And You Should Feel Bad”

  1. Never validate directly an user input. Myself use a variable, and never never never use REQUEST. You are making it vulnerable to GETS , not only to POSTs

Leave a Reply

Your email address will not be published. Required fields are marked *