Hi, Guest ~ Login or Register

Hash Salting: Uber-Security For Your Users

Hash Salting: Uber-Security For Your Users

Listed In PHP and MySQL » Security — Viewing Full Tutorial
As many of you will know, there are two ways which md5 hashes can be decrypted. There's brute forcing, which requires time, and then there's simple databasing, which requires a little bit of luck.



Though both of these methods are tedious, if someone's that desperate to get hold of a hash in order to compromise something on your website, they'll be able to. But, what if we made it even harder (almost impossible) to crack the encryption?



This is where a handy idea called a "salt" came into practice.



What's a salt?

Apart from being something that fast food companies use too generously on your chips, a salt is a suffix to a string which is going to be md5'd. It's a random string but it has to remain constant in order for anything to go anywhere.



Example usage:<?php
$data = $_POST['data']; // gets the data from the form

$salt = 'o4b2ehHj4'; // finds out salt

$salted = $data.$salt; // adds the salt

$secure_md5 = md5($salted); // md5's it

?>




So, we can insert $secure_md5 into our database knowing that the chances that somewhere on a cracking database, there probably isn't going to be a match for peppero4b2ehHj4, assuming that $data = "pepper".



How would I use this then?

The salt you need to keep safe somewhere, and it has to remain the same otherwise any hashes you create with any other string suffixed to it will not work. As a rule of thumb:
[QUOTE] Misfit said:

Every salt has a distinct taste. No meal will taste the same with a different type.

Basically, what the old man is saying is that if you use the salt to insert the hash into the database, you'll need to use the same salt to compare if a user is logged in.



Enough of the old man proverbs, here's something which you might find somewhat useful:<?php

// configuration

$config = array("salt" =&gt; 'o4b2ehHj4');



if($action == "register") {

  $password = $_POST['password'];

  $salted = $password.$config['salt'];

  $hash = md5($salted);

  $db-&gt;insert("$hash INTO `passwords`");

}



if($action == "login") {

  $hash = $db-&gt;select("hash FROM `passwords`");

  $password = $_POST['password'];

  $salted = $password.$config['salt'];

  if(md5($salted) == $hash) {

    $authenticated = true;

  }

  else {

    echo "Error, sorry!";

  }

}




You may be asking why I've put it into a configuration array. This is because you'll be needing to use this salt in all sorts of situations - logging in, registering, changing passwords and so on. It's just good practice!



If you want to be extra secure, you can add a pepper before the password, so it would be: $pepper.$data.$salt.



Unfortunately, because of the nature of md5, the ease of migrating all your passwords to the salted versions is pretty complicated, but not very hard.



In security terms, this salting is reasonably secure but doesn't bar out the possibility that a hacker could find out the salted password hash. Users could also have a common password thus resulting in the same final password hash. The way around this? Dynamic salting.



The beauty of this technique is that you don't even have to use any other fields or variables: you can take them from something as simple as the user's registration timestamp. Yup, you can use the unix timestamp of when they signed up to use a dynamic salt because it is constant and will never change. Here's another example for registration:<?php

$now = time();

$password = $_POST['password'];

$salted = $password.$now;

$hash = md5($salted);

$db-&gt;insert("$now, $hash INTO `passwords` (timestamp, hash)");

?&gt;




As for logging in, you'd only need to split your verification query into two:<?php

$user_salt = $db-&gt;select("username, timestamp FROM users WHERE username = '$username'");



$salted = $timestamp.$password;

$hash = md5($salted);



$authenticate = $db-&gt;count("hash FROM users WHERE username = '$username' AND hash = '$hash'");



if($authenticate == 1) {

  $logged_in = true;

}

?&gt;

[sidebox]You can do this with any field, but with timestamps it's slightly risky since the timestamp could be calculated if the date was shown on the site. I'd advise you to keep it quiet that it's the timestamp you're using for the salt.[/sidebox]
Summary

Salting is a way of increasing the security of hashes in a database. It makes it harder, but not still impossible for the hacker to compromise the database, though in theory dynamic salting would do the trick given that the signup date wasn't shown to the public, or if the timestamp had been manipulated beforehand. In terms of database design, it's going to be tedious converting everyone's passwords to hashes if your site has already been started up, so you can only really start salting passwords before all your users have signed up.

Working Beta

  1. The Forums
    These are mostly functional. If you see any weird bugs, post a thread about it and an administrator will do something.
  2. Tutorial Writing
    You can now submit tutorials to the brand new management system.
  3. Tutorials Home
    View tutorials by categories and search for them here.
  4. Shoutbox
    See below. Registered users only!

Register

Newest User

Say hi to Lirette25! Lirette25 joined on Monday, 14th July.

Sponsor

Check out Next day fake id

Shoutbox