Store your passwords in a secure way!

I was writing a basic register- and 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 than just running them through md5() or sha1(), so I wrote this function:

function password($password, $username, $saltglob = '2c62f9eb917de737b8184b8e5a793c89') {   
 
	/* save string length of username, password and salt */
	$userlen = strlen($username);
	$passlen = strlen($password);
	$saltlen = strlen($saltglob);
 
	/* split username, password and salt into string length + 1 */
	$user = ($userlen < 4) ? array($username, $username) : str_split($username, ($userlen/2)+1);
	$pass = ($passlen < 4) ? array($password, $password) : str_split($password, ($passlen/2)+1);
	$salt = ($saltlen < 4) ? array($saltglob, $saltglob) : str_split($saltglob, ($saltlen/2)+1);
 
	/* save ascii value of username, password and salt */
	$userval = ord($username);
	$passval = ord($password);
	$saltval = ord($saltglob);
 
	/* prepare an array of arguments and a format for vsprintf */
	$format = '%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s';
	$args   = array($username, $userlen, $passlen, $saltlen, $saltglob, $user[0], $user[1], $pass[0], $pass[1], $salt[0], $salt[1], $userval, $password, $passval, $saltval);
 
	/* vsprintf the arguments */
	$string[] = vsprintf($format, $args);
 
	/* rsort the arguments and run vsprinf again */
	rsort($args);
	$string[] = vsprintf($format, $args);
 
	/* sort the arguments and run vsprintf again */
	sort($args);
	$string[] = vsprintf($format, $args);
 
	/* hash each vsprintf result with md5 (raw) */
	foreach($string as $value)
		$password = hash_hmac('md5', $value, $password, true);
 
	/* hash	with sha512 (raw) */
	$password = hash_hmac('sha512', $password, $saltglob, true);
 
	/* return an md5 hash */
	return hash_hmac('md5', $password, $username);
 
}

This way, even if someone can produce a bruteforce against the algorithm they will never know where in the hash the salt pieces where placed. And of course we’ll salt it with a global salt (third parameter) which is hidden deep in a configuration file on our server, which requires the script kiddie to actually access your files to get it.

One thing’s for sure, I’ll use this for all my projects :) .

Edit: This function has been updated several times since the initial post because I like to make stuff more complicated than they actually have to be. The most recent one is the one above though (and is kinda overkill) :)