2011-11-04 107 views
0

我一直在读围绕着几个不同的导游/教程关于这个话题,发现如下:这是一个安全的方式来存储我的密码?

我知道,我所阅读有一个非常安全的方式来存储用户密码。我已经尝试了将第2个结合起来,而不是像第一个例子中那样使用mt_rand,我已经生成了我自己的动态盐。

这里是我的代码:

<?php 

    $static_salt = ""; // Removed value for obvious reasons 

    $dynamic_salt_choice = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; 
    $dynamic_salt_length = 40; 

    $dynamic_salt = ""; 

    $dynamic_salt_max = strlen($dynamic_salt_choice)-1; 

    for ($i = 0; $i < $dynamic_salt_length; $i++) { 

     $dynamic_salt .= substr($dynamic_salt_choice, rand(0, $dynamic_salt_max), 1); 

    } 

    $password_length = length($password); 
    $split_at = $password_length/2; 
    $password_array = str_split($password, $split_at); 

    $password = $password_array[0] . $static_salt . $password_array[1]; 

    $password_hash = hash_hmac('sha512', $password, $dynamic_salt); 

?> 

根据我这是获取一个静态的盐,生成一个动态的盐,我们再分割两个部分给定的密码在一个数组并添加静态盐在两个密码部分之间。

然后我们用密码sha12和动态盐一起散列。

我给你的问题是,这是更安全还是与我已链接到的2个方法一样安全?或者,我是否通过这种方式混合起来使它变得更加脆弱?

我还把它存在$password_hash在一个cookie用于cookie的自动登录是一个很大的禁忌?如果是这样,网站如何以安全的方式通过cookie记住你?

+0

可能重复的[安全散列和咸的PHP密码](http://stackoverflow.com/questions/401656/secure-hash-and-salt-for-php-passwords) –

回答

1

假设$dynamic_salt与最终的$password_hash一起存储 - 由于散列在没有它的情况下不可测试,因此此方案非常弱。使用盐确实可以防止彩虹表,但非迭代的HMAC会使此方案对于暴力攻击变得脆弱。 (盐的长度并不好,因为它是散列输入中已知的常数,将它放在原始密码的中间并不是真的有帮助。)

总体而言,该方案远远弱于bcrypt(),因为它只有(有效)迭代哈希两次。你真的没有比下有余,如果你只是用一个简单的方案,如存储的密码:

$salt = uniqid(); 
$password_hash = hash_hmac('sha512', $password, $salt); 

但你还是最好不要使用别人的(久经考验的)密码加密程序,而不是烹饪你自己的。


关于在cookie中使用的密码哈希 - 这是要避免的,因为它允许对数据库的只读访问(如一个攻击者,通过SQL注入攻击或偷来的备份)在您不知道或更改密码的情况下冒充应用程序中的任何用户。这也意味着,如果用户的计算机已设置为自动登录,则会在其上存储密码哈希。我会避免这一点。

更好的方案可能是在用户选择自动登录时在Cookie中设置随机生成的随机数,然后将该随机数的散列存储在数据库中。这样,服务器可以检查登录密钥的正确性,而无需“记住”它。

+0

感谢您的回复,我很可能会坚持一种经过验证的测试方法。至于cookie的情况,我有点困惑。当然,将会话令牌存储在用户计算机上并将其链接到帐户仍然很危险,因为这可能是伪造/猜测/被盗等等。这是一个安全的方法? – Joe

+0

任何允许用户登录的方案在某些时候都会涉及在用户的计算机上存储与他们的帐户相关的*东西*,这是不可避免的。这里最重要的是你要存储的东西不是他们账户的重要部分(比如密码哈希),哪些不是直接存储在数据库中的数据。 – duskwuff

0

盐可以使用,但它有它自己的局限性。使用bcrypt.More信息的另一种方式可以在http://www.openwall.com/phpass/

发现,我认为这SO文章是绰绰有余Secure hash and salt for PHP passwords

+0

这是我一样链接文章至于,我的问题仍然存在......是我的方式比那里发布的和/或我链接到的其他文章更安全吗? – Joe

2

我试图提高系统的安全级别与我的网站更

好吧,让你知道,没有密码哈希应用程序可以增加你的网站安全性,甚至有点。
您必须专注于其他更重要的事情,例如SQL和文件注入,XSS和CSRF漏洞。 如果您保持您的网站安全,它会保持您的密码安全,只是一个副作用。

接下来你要关注的事情是密码强度没有散列可以保护一个愚蠢的密码joe123

至于哈希本身 - 你可以使用任何你想要的,一些基本的东西,如使用注册时间或电子邮件等一些理智的盐和任何散列函数的一些迭代次数就足够了。不要把太多的意义放在哈希中。它不是那种需要非常注意的东西,因为它创造了一些非常安全的原始算法。

我给你的问题是,这是更安全还是与我已链接的2种方法一样安全?或者,我是否通过这种方式混合起来使它变得更加脆弱?

不知道如果你信任我(我打赌你不会)但所有这些方法都足够安全并且不需要隐瞒。并且影响网站的安全性,但只能使用自己的密码,以防使用您网站中的其他漏洞盗取它们。

我也把它存储在一个cookie中的$ password_hash一边用户名cookie自动登录是一个大的禁忌?

我不认为这是明智的事情来揭示哈希本身。但同样,它不影响网站安全,但密码只有潜在的潜在漏洞。如果你的散列和密码足够强大,一个逻辑就是让我说它足够安全。

+0

我也尽我所能保护免受SQL注入等(我会去重写那部分内容) - 但是,如果他们正在阅读,谢谢您为他人指出这一点。因此,“这是最好的方法”并不是一个确定的火焰 - 只要使用动态和静态的盐,几乎就可以走了?怎么样的cookie情况? – Joe

+0

这一点不在SQL注入中,但密码哈希不会影响您的网站安全性。 –

1

这似乎是一个合理的盐水计划,虽然可能矫枉过正。它可能不需要长达40个字符 - 你只是试图炸开彩虹桌的大小,而不是做出不可估量的随机数 - 但是长时间不会造成伤害。

对于自动登录,您应该(在cookie中)存储与指向用户帐户的数据库条目对应的随机令牌。当用户更改密码时,请删除该用户的所有条目。当生成此令牌时,rand()不够好 - 您需要一个安全,不可猜测随机数。不幸的是,PHP并没有真正的安全随机数内置设施 - mt_rand()差不多,但我个人会在Linux系统上直接从/dev/urandom读取随机字节,并使用它来生成我的随机数。

+0

会不会session_id()在这里是一个很好的选择? – Espen

相关问题