2011-08-09 141 views
0

我使用crypt()加密在PHP这样的:在PHP中使用crypt()加密密码的安全性如何?

<?php 
$password = sanitizing_func($_POST['password']); 
$var = crypt($password, 'ab'); 
?> 

如何安全是什么?

找到一个更好的解决方案在这里:openwall phpass

由于Edward Thomson

+1

建议阅读 - http://twogrammers.stackexchange.com/questions/51403/what-should-web-programmers-know-about-cryptography,进一步信息化文章,顺便说一句,你不是在消毒用户输入? – Kumar

+0

哦,是的,我这样做,这是一个例子,我不把POST ['密码']照原样。我要读你建议链接 – regrunge

+0

你不会信任用户输入! – Kumar

回答

1

这是不太安全比,如果你只是用crypt它被设计的方式,用密码作为第一个参数和盐作为第二。

现在您使用用户的密码作为salt来加密已知的明文。如果您的系统使用MD5 crypt,那么您只将salt空间限制为12个字符,因此您将用户密码的空间截断为12个字符。更糟糕的是,我的系统要求我在盐上使用前缀以指定我的地下室,否则我会得到旧学校crypt,这意味着您有两个字符为盐。因此,您已将用户密码的可能长度限制为两个字符。此外,即使在此时运行crypt也没有任何意义,您可能只需存储它们的两个字符密码,因为salt是以密文为前缀的,以便后续调用crypt可以传递相同的盐。因为盐的字符空间限制为A-Z,a-z,0-9,“。”,“/”,所以您在salt中使用它来限制密码的字符空间。即使您从代码示例中切换参数,您也会为每次调用使用相同的盐数据。这意味着每个密码都有相同的盐。因此,如果您的密码表暴露出来,那么使用字典式攻击来破解计算量会更小。

换句话说,交换密码和salt参数是一个致命的错误。

最后,根本没有理由调用crypt两次。如果你想更好的加密,使用更好的算法,不要更频繁地调用它。例如,如果你使用的是DES crypt,那么无论你多少次调用它,它仍然是一个古老的算法。 (我似乎还记得读过一个算法的多次传递可能会不经意地产生被削弱的密文,但我没有Schneier在我面前)。

你想要做的是行业标准:使用强壮的地下室,将第一个参数的密码作为第一个参数并将随机盐数据作为第二个参数传入,并确保您传递的盐的最大允许字节数。

+0

好吧,现在我在随机盐上有点失落:我怎么把它弄回来? 我的意思是如果盐是随机的,我该如何在登录时检查它?那里不是更好吗? <?php $ var = crypt($ _ POST ['password'],CONSTANT); ?> – regrunge

+0

不可以。您的盐在密文前加上以获得返回值。对于旧学校DES crypt而言,它将是前两个字符。所以你选择两个随机字符,并cryptedPass = crypt(PASSWORD,“ab”);其中“ab”是随机盐。加密后的返回值将以ab,随机盐为前缀。所以你存储了加密通过结果。然后,当用户再次输入密码时,您可以获取您存储的加密密码,以便您可以获得原来使用的盐。然后再用他们的输入和原始盐,再比较cryptedPass来运行crypt()。 –

+0

谢谢爱德华,只是出现的密码有点儿短,我习惯了很长的字符串与md5和朋友(我知道他们是如何不安全,他们与raimbow表)...以及我想信任crypt – regrunge