2014-05-13 119 views
0

我创建一个登录系统在PHP中,我遇到哈希。PHP crypt()函数VS.哈希()函数

有人可以告诉我为什么如果我使用hash()与sha512它生成一个128字符的字符串,而使用crypt()与sha512它只有118个字符(但只有103个字符的散列)?

实施例:

$password = "password"; 
$hashed = crypt($password, '$6$rounds=5000$'.core::genSalt().'$'); 
$hashed2 = hash('sha512', $password); 

echo "pwd hashed with hash() -> $hashed<br>"; 
echo "hashed pwd length? ".strlen($hashed); 
echo "<br>-----<br>"; 
echo "pwd hashed with crypt() -> $hashed2<br>"; 
echo "hashed pwd length? ".strlen($hashed2); 

并且它导致:

pwd hashed with crypt() -> $6$rounds=5000$HGWYWN+gVBLsotI5$sxqlewzU4pn4Z0/.5DlX6orE9Mw2W0Z7VJ6Qp8cCQdDqGvCJHqgiG6fYQjI2dSm78ErfXQ8QbMjq1JCVl2Hah0 
hashed pwd length? 118 

pwd hashed with hash() -> b109f3bbbc244eb82441917ed06d618b9008dd09b3befd1b5e07394c706a8bb980b1d7785e5976ec049b46df5f1326af5a2ea6d103fd07c95385ffab0cacbc86 
hashed pwd length? 128 

谢谢

+3

[password_hash](http://docs.php.net/manual/en/function.password-hash.php)比两者更好,它产生在它自己的 –

+0

散列函数盐AREN没有加密功能。它们不是为了扭转这一过程而设计的。另外:你的回声是相反的。第一行('$ hashed'的回声)来自'crypt()'而$ $ hashed2'来自'hash()' – ccKep

+1

@Arian是的,如果OP的PHP是5.5 ---如果不是,那么使用兼容包(如果PHP <5.5)https://github.com/ircmaxell/password_compat/ –

回答

3

散列()使用的十六进制表示([A-f0-9]),而隐窝( )似乎使用[a-zA-Z0-9.//]从我看到的。

对于十六进制表示,每个字符包含4个(16个需要4个二进制数字)位的信息,对于crypt,每个字符包含6个(64个需要6个二进制数字)。

我们知道,SHA-512产生一个512位的散列,所以:

  • 散列():512/4 = 128个字符
  • 隐窝():512/6 = 85,33〜= 86个字符,如果我们剥离加密模式,回合和盐($ 6 $ rounds = 5000 $ HGWYWN + gVBLsotI5 $),则与字符长度匹配。在您的例子是“sxqlewzU4pn4Z0/.5DlX6orE9Mw2W0Z7VJ6Qp8cCQdDqGvCJHqgiG6fYQjI2dSm78ErfXQ8QbMjq1JCVl2Hah0”

作为一个例子,看看当我们使用10,16或36个字符来表示数量会发生什么。

$decimalNumber = 123456789; 
var_dump(base_convert($decimalNumber, 10, 16), base_convert($decimalNumber, 10, 36)); 
+0

谢谢,完美答案 – lorenzoasr