note 81708 deleted from function.md5 by tularis
| From: | tularis@php.net | Date: | Thu, 14 Jul 2011 22:51:33 +0000 |
| Subject: | note 81708 deleted from function.md5 by tularis | ||
| References: | 1 | Groups: | php.notes |
| Request: | Send a blank email to php-notes+get-181529@lists.php.net to get a copy of this message | ||
Note Submitter: Stevish at gmail dot com
----
I have sort of devised my own compilation lots of peoples' ideas for creating a secure, custom
hash.
In order to keep my real hash-generator safe from prying eyes, I will simply give you the basic idea
with random examples.
I started by making three hashes using three salts. If you want, you can use something like
"crypto" below (http://us.php.net/manual/en/function.md5.php#70258) for one or more of the
hashes.
<?php
$salt1="something custom";
$salt2="blahblah";
$salt3="differentblah";
$hash1=sha1($salt1.$source)
$hash2=sha1($salt2.$source);
$hash3=md5($salt3.$source);
?>
Then here's where I think my idea is unique:
<?php $h = $hash1.$hash2.$hash3; ?>
Now, you want to shuffle them together, to make them practically impossible to separate. For that, I
implemented the "scramble" idea from below
(http://us.php.net/manual/en/function.md5.php#59241):
<?php
$scrambledhash = $h{18} . $h{110} . $h{88} . $h{65}/*...etc*/;
?>
This will scramble the characters of that hash in your predetermined (but supposedly random) order.
ALMOST DONE!
I found the final step at http://phpsec.org/articles/2005/password-hashing.html
.
The idea is that when a user enters a new password on registration (or changes their password). The
function will create a random salt to help scramble the users password. Then, in order to make it
possible to compare passwords in the future (since the salt was randomly created), the salt is
appended to the beginning of the hash.
My twist on this is to spread the salt out through the hash. Then to extract the salt, you would use
something similar to the scramble function above.
Assuming you use a 5-digit salt (although it really should be longer), which is stored in the 15th,
93rd, 34th, 72nd and 10th digits of your final hash (in that order), this is what it would look
like:
<?php
$salt=$hugeRetrievedHash{14} . $hugeRetrievedHash{92} . $hugeRetrievedHash{33} .
$hugeRetrievedHash{71} . $hugeRetrievedHash{9};
?>
Remember that the first character in a string is number 0!
ALL DONE!!!
Now for all that compiled into one function!
<?php
/* When creating a password, use superHash($pass);
** When checking a password, use <?php if(superHash($pass,$hash)==$hash);?>
** where $hash = the hash you are checking against.
*/
function superHash($source, $storedSalt = null)
{
if ($storedSalt === null)
{
$salt = substr(md5(uniqid(rand(), true)), 0, 5);
/*Note: The number 5 above is the length of the salt. This particular method only allows for a
maximum 32 character salt.*/
}
else
{
$salt = $storedSalt{14} . $storedSalt{92} . $storedSalt{33} . $storedSalt{71} .
$storedSalt{9};
/*This will obviously change based on how you distribute your salt in the hash, and how long it
is.*/
}
$salt1="something custom";
$salt2="blahblah";
$salt3="differentblah";
$hash1=sha1($salt1.$source.$salt);
$hash2=sha1($salt2.$source.$salt);
$hash3=md5($salt3.$source.$salt);
$h = $salt.$hash1.$hash2.$hash3; //add salt to the mix
$scrambledhash = $a{70} . $a{43} . $a{37} . $a{52} . $a{91} . $a{29} . $a{10}/*...etc*/;
/*Here, we would look for the numbers 0, 1,2, 3 and 4 (which is where $salt was placed), and use
their relative location (like 15th, 93rd, 34th, 72nd and 10th), and use those numbers (minus 1) in
the statement above.
Note that there are 117 characters to be accounted for (112 for the hashes + 5 for the salt).*/
return $scrambledhash;
}
?>
SECURITY NOTE!
From what I read, it's probably safest to put this function in it's own file outside of
the public domain, and simply include() the file in every script that needs to use it.
*Whew* and that, folks, is all I got.