Update (2010-05-29): Did some major changes to the function, latest version can be found here.
I was writing a basic register-/login-script yesterday and when I did the part where it hashes the password with a salt I realized that there should be a more secure way to store passwords, so I wrote this function.
function salt($password, $username, $salt = 'b_Il-w63') {
/* Split the username and the password into two parts with "(string/2)+1" chars in each */
$user = str_split($username, (strlen($username)/2)+1);
$pass = str_split($password, (strlen($password)/2)+1);
/* get the first character in the username and the password and convert them to its ascii value */
$user_ord = ord($username[0]);
$pass_ord = ord($password[0]);
/* merge all variables into a special pattern */
$string = sprintf('46%s-3S%s-%u-%s-%u-1a%s-F4%s', $user[0], $pass[0], $user_ord, $salt, $pass_ord, $user[1], $pass[1]);
/* hash the string with sha512, and then it again with md5 */
$hash = hash('sha512', $string);
$return = hash('md5', $hash);
/* reverse the md5 hash and return it */
return strrev($return);
}
This way, even if someone can produce a rainbow table for the algorithm, and has the salt to do it with, they will never know where in the hash parameter the salts was placed, because they don’t know the length and first letter of the actual password. And of course we’ll salt it with a string (third parameter) which is hidden deep in a configuration file somewhere, which requires the skiddie to actually access your files to get it.
When the string is ready we hash it with sha512 and then again with md5 (less byte to store in the database) and after that the function returns the hash. One thing’s for sure, I’ll use this for all my projects
.