PHP - Better hash functions

From Global Programming Syntax

Jump to: navigation, search

Sometimes you might wonder what is the best hash function. Guess what, most of them can be cracked by a reversed lookup (with the exception of whirlpool). Especially with the 2011 IBM supercomputer coming out with 1.6TB ram and 20 petaflops (floating points per second). With the new technology coming out it is becoming faster and easier to crack hashes so something needs to be done and that something is in this page. Generally a salt alone is not secure enough because when a hacker dehashes the hash they can work out what is the salt and delete the salt. However, if you have a hash inside a hash then that is when it starts to become difficult to dehash because twice as much cpu power is required to dehash the hash depending on which hash algorithms you choose. So the answer to these questions on how to prevent such an attack is in the below sections.

Standard Hashing

If you are only worried about the average hacker trying to crack a hash then you may use any of the below hash function. This hash function will make it very hard to dehash but is still possible to dehash under the standard reverse lookup algorithm if such recourses are available to the hacker.

function truehash($hashzzz) {
return hash('sha256',hash('whirlpool',$hashzzz));
}

The above hash uses a reasonable amount of cpu and does an ok job but if you are really worried about a hacker getting the data then it is best to wipe out half the whirlpool data in the above function. The following will stop those supercomputers from cracking the hash as the below hash basically makes its own algorithm.

function securehash($hashzzz) {
return hash('sha256',substr(hash('whirlpool',$hashzzz),64));
}

The reason why you would bother, it is increasingly becoming easy to crack hashes and this website will eventually host a 5 digit hash cracker for crc32, crc32b and sha1. And that is just with basic cpu power. Imagine a hacker who uses a virus bot network of 4000 computers to find the original string all processing at the same time. Or even a hacker who hacks 7 of the worlds most powerful computers. Now that would be scary as virtually every hash would be crackable. So the only true solution is to re-invent the wheel and do a custom hash or at least modify the result of the hash in some way other than just a salt. And so if your trying to store data in a way you can't do a reverse lookup then use one of the functions on this page or something like it.

Video

Below is a video for "standard hashing" for those who prefer to watch instead of reading. [video src=php_hashing size=600x474]

Custom Hashing

Custom hashing can have it's advantages and a few disadvantages. The below function will hash a string and not only does it hash the string, you can specify a second string to mix in with the hash like a salt but more effective. At the same time this function will compress the string maintaining the strings information so it is unique. In other words every input will bring a unique output however if you do the same input twice then the same output will occur twice. Be careful when using this hash function to compare hashes as every input needs to be the same. However only the first input is actually required. Below is a list describing each input from left to right

  • Input 1 - The string to hash
  • Input 2 - A salt/random string to use on all your hashes
  • Input 3 - Weather you want to mix in the salt or not. By default the salt is mixed in making a larger output. Alternatively you can set it to false to reduce the size of the return output and change the algorithm but the size will only be reduced if a salt is specified.
<?php
function hash_string($string,$extrachars='',$mixsault=true) {
$str=array();
if (strlen($string)>3) {
$len=floor(strlen($string)/2);
if ($mixsault==false) {
$long=str_split(substr($string,0,$len).$extrachars.substr($string,$len),1);
} else {
$string=substr($string,0,$len).$extrachars.substr($string,$len);
$long=str_split($string,1);
}
} else {
$long=str_split($string.$extrachars,1);
}
for ($i=0;isset($long[$i]);$i++) {
if (!isset($charconvert[$long[$i]])) {
$charconvert[$long[$i]]=true;
}
}
if ($mixsault==false) {
ksort($charconvert);
}
$i=2;
foreach ($charconvert AS $key=>$val) {
$charconvert[$key]=$i++;
}
$amount=count($charconvert);
unset($long);
$arr=str_split($string,2);
while (!empty($arr[0]) || $arr[0]===0) {
for ($i=0;isset($arr[$i]);$i++) {
$char=str_split($arr[$i],1);
$arr[$i]='';
if (empty($charconvert[$char[1]])) {
$tmp=1; } else {
$tmp=$charconvert[$char[1]];
}
 
$v=(($charconvert[$char[0]]*$tmp)+32+($amount-$tmp));
if ($v<256) {
$str[]=chr($v);
} else {
$str[]=$char[0];
$arr[$i]=$char[1];
$arr=implode('',$arr);
unset($arr);
$arr=str_split($arr,2);
unset($arrs);
}
unset($v,$tmp);
}
}
unset($arr,$char,$charconvert);
return implode('',$str);
}
 
echo hash_string('This is to be hashed','this is like a sault',false); //outputs: >–7FÊ3:JŽR
echo hash_string('This is to be hashed','this is like a sault',false); //outputs: >–7FÊ3:JŽR
echo hash_string('This is to be hashed','this is like a sault',true); //outputs: 1=BF^@=BFN‘jG½ftjF:Ä
echo hash_string('This is to be hashed','this is like a sault',true); //outputs: 1=BF^@=BFN‘jG½ftjF:Ä
echo hash_string('This is to be hashed'); //outputs: .:?C[XaA7—
echo hash_string('This is to be hashed'); //outputs: .:?C[XaA7—
echo hash_string('This is to be hashed','',false); //outputs:  ;ƒ4?™07G{O
echo hash_string('This is to be hashed','',false); //outputs:  ;ƒ4?™07G{O
?>
Personal tools
languages
page stats
Toolbox