PHP Password Salt and Pepper using sha1 MD5 Hash
Adding salt to passwords has become a very popular topic. In this tutorial we will look at adding more then just a little salt in hope to make the passwords stored in the database a lot more complicated to break.
What we aim to do is change “HelloKitty” into “bd6656780b4fcad95b4326dd6ee46cbcdb4d8a”.
This is the final code:
echo saltPlease($pepper);
function saltPlease($pepper){
$salt=0; //create some salt
$dinner=$pepper; //add our pepper to our dinner
$pepper= preg_split('//', $pepper, -1, PREG_SPLIT_NO_EMPTY); //split out the pepper into an array
foreach($pepper as $key => $value){
$salt+=ord($value); //get the ascii values of our pepper
}
$sodium = $salt % 4;
$salt = $salt % 5; //devide the salt by 5 and return the remainder
if($salt==0){$salt="Dawdlerubefacient";} //based on the salt value we will choose the type of salt
if($salt==1){$salt="Slubbingbilly";}
if($salt==2){$salt="fearsomeTogo";}
if($salt==3){$salt="cephushandclasp";}
if($salt==4){$salt="Conquestpriggishness";}
if($sodium==0){$sodium="earnestnessClovehook";} //based on the salt value we will choose the type of salt
if($sodium==1){$sodium="GyroseAcclamation";}
if($sodium==2){$sodium="cartelhorsebarn";}
if($sodium==3){$sodium="Chivieddulles";}
$dinner=md5($salt) . sha1($dinner) . hash('sha256',$sodium);//add the salt to our dinner and mix it right up
$dinner=sha1($dinner);//mix our dinner up some more
return $dinner;
}
The common stories in the media about hacking related to simple scripts being used to get access a database with unencoded passwords. Generally the sites broken into are less popular sites which have not seriously considered security, or thought the cost was too much. The hackers hope the users have used the same password, username and email address for other sites they are a member of such as FaceBook. Adding salt to stored passwords and using an encryption method has proven to be floored as md5 has been reversed engineered and the salt is pretty much the same as it becomes obvious that the word “salt” is on the start of every password.
The Create My solution was to make it just that little bit more annoying and complicated to reverse adding enough deterrents for the hackers just find the time to break the encoding just too annoying. Along with encoding the password in the database you need to add SQL injection protection measures.
The Solution
The solution is composed of a method to make a fairly random raw password and then a highly encrypted password using several encryption methods.
Method
- Analysis of the password to find a number using the sum of the ASCII values
- The results is divided by 5 and the remainder is used for the salt and divided by 4 and the remainder is used for the sodium (I recommend much higher values used)
- The value of the salt and sodium is used to select some random text (the higher the division the more values which need to be added
- The salt, dinner and sodium is encrypted using three different methods and concatenated to make a very long encrypted password
- Once more the password is encrypted just for good measure
Code Broken Down
First $pepper (the password) is set to HelloKitty and the second line is to print the result of the encryption of $pepper.
echo saltPlease($pepper);
Next we have our function saltPlease. We set salt to 0 and add the $pepper to the $dinner. $salt = 0, $pepper=”HelloKitty” and $dinner=”HelloKitty”.
$salt=0; //create some salt
$dinner=$pepper; //add our pepper to our dinner
To create some randomness to the password while maintaining the structure the ASCII values are summed up to produce a value. First the $pepper string is transposed into an array then each ASCII value is derived using the ord() function. $pepper = ‘H’,'e’,'l’,'l’,'o’,'K’,'i’,'t’,'t’,'y’ and $salt=1033
foreach($pepper as $key => $value){
$salt+=ord($value); //get the ascii values of our pepper
}
Using the MOD operator (%) we are able to set the sodium and salt to the remainder of the value of salt divided by 4 and 5 retrospectively. Sodium and Salt should be different so you don’t always have the same salt with the same sodium. I recommend using much higher values then 4 and 5. $salt=3 and $sodium=1.
$salt = $salt % 5; //devide the salt by 5 and return the remainder
As 5 was used for the salt, it is set to one of the following 5 values. $salt=”cephushandclasp”
if($salt==1){$salt="Slubbingbilly";}
if($salt==2){$salt="fearsomeTogo";}
if($salt==3){$salt="cephushandclasp";}
if($salt==4){$salt="Conquestpriggishness";}
As 4 was used for the sodium, it is set to one of the following 4 values. $sodium=”GyroseAcclamation”
if($sodium==1){$sodium="GyroseAcclamation";}
if($sodium==2){$sodium="cartelhorsebarn";}
if($sodium==3){$sodium="Chivieddulles";}
This is where it get a little crazy.
md5($salt)=cc92e6fbd43788cac81ed0e78ab63f47
sha1($dinner)=5aa28664dfab74ba2d0ad632df19fc3150333a73
hash(‘sha256′,$sodium)=5df3ce0c86289881f9ff983a7c63676c7cc836de8a75a60b2d7ca1ec0af59508
$dinner=cc92e6fbd43788cac81ed0e78ab63f475aa28664dfab74ba2d0ad632df19fc3150333a735df3ce0c86289881f9ff983a7c63676c7cc836de8a75a60b2d7ca1ec0af59508
One last mix up of the dinner. $dinner=b2bd6656780b4fcad95b4326dd6ee46cbcdb4d8a
Finally dinner is return for the password. This then is stored in the DB and the same function is used to encrypt the password to be equal when the user logs in.
}

http://www.wordswarm.net/ was used to generate the words for the Salt and Sodium.
I’m not an expert and I’m sure this was just a clever example, but don’t you think this is a lot of work? Since you’re using sha256, you may as well hash the data with the salt directly.
[php]
$someData = ‘my very secret password’;
$salt = ‘aq:=IOz6`|q686iGim(!LN712d5Or6*s*KzBca,2).*bNW)-8@Nf]r^:93Kok8tR’; // from wordpress, http://api.wordpress.org/secret-key/1.1/
$to = $salt . $someData;
$hash = hash(‘sha256′, $someData);
[/php]
I like it.
thank you very much, I learned a lot
Incredibly, you managed to come up with something worse than unix crypt() in 1976.
Why would u take so much effort ?
$pass = escape_etc ( $_POSt['passowrd''] );
$user = new User;
$user->create = time();
$user->email = ‘mail@mail.com’;
switch( substr( $user->created,0,1 ) ) {
case 1:
$user->pass = md5(‘your’ , $pass . $user->created . ‘mother’);
break;
case 2:
$user->pass = md5($pass . substr( $user->created, 0, 5) . ‘smells’);
break;
case …
}
$user->save();
if your algorithm is known, and the time of registry know (since you have to store this info to compare the pass it could be) then to crack it i just need to do this:
$pass=one result of a rainbow table attack
$thetime=the result bit i stole from the database telling when they were created
$hashedPass=the hashed pass i stole from your datbase
if(md5(‘your’.$pass.$time.’mother’)==$hashedPass)
{
doStuff();
}
and i can do the other one too, under the same algorithm (since i know $user->created, i know which one its using)
the thing with salts is both the salt AND the algorithm to make them have to be secret or someone can just crack it.
yours has the advantage though that the algorithm has 16 permutations (but to be honest it will almost always evaluate to 1, you needed substr(-1,1) to get the last digit…you got the first digit which almost never changes) but if you know the method you can derive the pass.
[...] Starten wir mit dem Thema Sicherheit und PHP, immer wieder bekommt man es in den Medien mit, Datenbanken mit Passw?rtern werden gestohlen. Um nun mindestens mal die Kennw?rter sicher(er) abzulegen empfiehlt es sich einen sogenannten “SALT” zu verwenden. Eine relativ sch?ne Methode findet ihr hier “PHP Password Salt & Pepper“. [...]
What I don’t understand about all this salt n pepper… Isn’t it always like this, that as soon as the attacker knows my database and my function, encoding it, that it becomes very easy to crack the password?
I’m surely not an expert, but just trying to understand such issues better…
In the example given, wouldn’t it be possible, to do a bruteforce easily as well, if i get hold of the function???
e.g.
[PHP]
function bruteforce() {creates different possible passwords
from either dictonary, or systamatic approach, e.g.
return ‘HelloKitty’;}
//then i do:
$numberOFtrys=100000000000000;
whilte ($i<$numberOFtrys){
$test=bruteforce();
if (saltPlease($test) == $HASHfromYOURdb){
echo $test." is the password";
exit;
}
}
[/PHP]
So as far as I understand this issue, salt (and pepper) make a password safer, as long as "just" the database has been accessed by the attacker, but as soon as he gets hold of the function used, as well, it doesnt matter how complex the encoding algorythm is, right?
Or am I completly wrong on this, then please correct me!
kind regards
[...] PHP Password Salt and Pepper using sha1 MD5 Hash [...]
MD5 hasn’t been reverse engineered. The site is simply storing the hashes that were generated, and tries to match those (so they’re using the “rainbow table” approach). When you try to “decrypt” a key they don’t know about yet, you’ll get a simple “Sorry, this MD5 hash wasn’t found in our database”. But when you encrypt that and try it again, it “magically” appears (now how would they do that :p).
That is a form of reverse engineering.
Awesome love it
@Nico,
i tryed a Bruforce Script with
for($i=0;$istore into http://www.tools-blog.de/
therefore i wrote a md5 hash generator
i check -> if md5 Hash exissts return false
$hit[] = check Response;
}
but there are no equal hashes
thx for this arcticle