用盐认证用户登录

用盐认证用户登录

问题描述:

我使用salt加密我的用户密码。 我正在使用PHP,下面是用户注册期间发生的事情的快速示例。用盐认证用户登录

这就是:

PHP代码:

// Gives me my random key. My salt generator. 
    $salt = uniqid(mt_rand()); 

    // My password via what users inputs. 
    $userpwd; 

    // Then the encryption. I use a HMAC hash. 
    $encrypted = hmac_hash("sha256", $userpwd, $salt); 
?> 

现在,在我的剧本都为我工作。但我的问题是,我如何认证用户登录?新的加密密码是随机的,所以我无法将登录表单中的密码与数据库中保存的加密密码进行比较。

我搜索了并找不到解决方案。也许我没有足够努力搜索,但有没有解密密码的方法?我可以通过脚本来验证用户身份?

您以同样的方式散列用户输入的密码,然后比较散列是否与您存储的密码相同。

if (hmac_hash("sha256", $_POST['password'], $saltFromDatabase) === $hashFromDatabase) 
    $login = true; 

您还必须存储盐,因为它对每个用户都不同。我还建议使用在应用程序中保持不变的第二个salt(存储在硬配置文件中,这样即使数据库受到攻击,密码仍然安全)。

注意:散列是不是与加密相同;这是一个不可逆转的过程。

+0

谢谢,那就是我会做的。我把我的盐储存在配置文件中。我读过很多人说将盐储存在分贝中,但是我对它感到不舒服。只是将数据库妥协了。 – Mario 2010-11-09 14:31:10

+1

但请记住,为每个人使用相同的盐会减少强力攻击者所需的计算时间。 – 2010-11-09 15:05:19

+0

如果不止一个人拥有相同的密码,它也会导致相同的散列。每个用户有一个盐(每个密码)要好得多。 – Aether 2010-11-09 16:09:25

你不解密你存储的内容。您对输入的密码进行散列并将其与注册时存储的密码进行比较。这是因为如果两个哈希匹配(所有意图和目的),您可以确信源数据匹配。

你的盐需要是恒定的,而不是随机的。通过这种方式,当你对密码进行密码检查时,你所要做的就是再次用盐对输入进行哈希处理,结果的哈希应该与之前出现的相同。

+0

好的。所以不要随机产生盐?使用恒定的盐?我读过很多人在db中保存盐串。这是一个很好的做法吗? – Mario 2010-11-09 14:27:59

+1

根据定义,盐不*常数,而是随机值。 http://*.com/questions/1645161/salt-generation-and-open-source-software/1645190#1645190 – Jacco 2010-11-09 14:59:12

+0

@Jacco常数到密码标识的那条信息。所以在这种情况下,可能是一些用户特定的数据。独特,而不是随机的。 – 2010-11-09 19:14:44

您需要为每个用户的密码生成一个唯一的salt,然后将salt的值存储在某个可以检索它的地方。例如,通过将盐保存到user表以及用户名和散列密码。这样,当你去认证一个用户时,你可以提取已知的salt并通过你的函数运行它。

这里是一个包含更多信息的文章:Storing Passwords - done right!

以及有关盐的更多信息:salt-generation-and-open-source-software

+0

不知道为什么这会被低估... – 2010-11-09 14:51:19

+0

盐必须是随机的。 (如果它不是随机的,我们称之为关键)http://*.com/questions/1645161/salt-generation-and-open-source-software/1645190#1645190 – Jacco 2010-11-09 14:58:02

+3

当然。在那篇文章中:“每当你创建一个新密码或更改密码时都要使用新盐”。我同意每次生成密码时都需要计算新的独特的盐。然后,您可以按照我的建议将该盐存储在数据库中。我看到我的答案真的没有解释清楚,所以我修改了它... – 2010-11-09 15:50:08

你加密用于登录,并与数据库中的加密的密码进行比较的密码。 :)

您计算用户输入的密码的哈希,就像您在注册时一样。请注意,代码是半伪代码,您需要将其调整为您的库或函数。

$res = db('SELECT etc FROM users WHERE user=? AND pass=?', 
    $_POST['user'], hmac_hash("sha256", $_POST['pass'], $salt)); 
if(numRows($res) > 0) { 
    // continue with authentication 
} 

如果盐存储在数据库,那么你就必须要么第一取水的时候,还是在数据库进行比较。

+1

你应该首先从数据库中获取salt,而不是将非哈希密码发送到数据库。 – Jacco 2010-11-09 15:05:11