密码“盐” - 我做得对吗?

时间:2012-04-02 23:52:31

标签: php mysql session encryption login

我开始想,也许我的登录系统不如我想象的那么安全。 首先,我将用语言向你解释我正在做什么。

当用户注册时,会生成16个字符的盐。 我将盐存储在一个名为“salt”的字段中的数据库中 我将散列密码+ salt(它们被散列在一起hash("sha256", $salt.$password);)存储在一个名为“password”的字段中

当用户尝试登录时,我会从数据库中获取“密码”字段和“盐”字段,以及其他一些内容。

要检查他们是否正确输入了密码,我会这样做:

$hashed = hash("sha256", $row['salt'].$pass);
if ($row['password'] == $hashed) {
//success

($ row是数据库中提取的数组。$ row ['salt']是数据库中的salt,$ pass是他们输入的密码,$ row [“password”]是散列传递+ salt在数据库中)

我在想,而且在我看来,我的盐提供的安全性很小(或根本没有)。我向你们提出的问题就是:我的方法是否提供了额外的安全性(或者甚至是安全的吗?)

此外,我还有第二个问题。我想验证这个“检查登录”脚本不能被欺骗/欺骗,以便在没有密码的情况下进入某人的帐户。

session_start();
require_once 'db_connect.php';
//If the session variable "id" isn't set (i.e. they aren't logged in)
if (!isset($_SESSION['id'])) { 
    //Check if they wanted to be "remembered" (so they have 2 cookies
    if (isset($_COOKIE['rem_user']) && isset($_COOKIE['rem_pass'])) 
    { 
        $query = "SELECT 
                      id, 
                      password, 
                      auth, 
                      email, 
                      username 
                  FROM users 
                  WHERE 
                      username='".$_COOKIE['rem_user']."' 
                  AND active IS NULL"
        $res = mysql_query( $query );
        if (mysql_num_rows($res) == 1) 
        {
            $row = mysql_fetch_array($res);
            // If the "remember me" cookie containing their password 
            // is equal to the one in the database, log them back in.
            if ($_COOKIE['rem_pass'] == $row['password']) 
            { 
                $_SESSION['id'] = $row['id'];
                $_SESSION['username'] = $row['username'];
                $_SESSION['auth'] = $row['auth'];
                $_SESSION['email'] = $row['email'];
                $logged_in = 1;
            }   
        }
    } 
    else 
        $logged_in = 0;
} 
else 
    //Since the session variable "id" WAS set, they ARE logged in. 
    $logged_in = 1; 

我认为登录的唯一方法是......

  1. 欺骗一个我认为没有服务器访问权限的会话变量
  2. 使用加密密码+ salt欺骗cookie,我相信如果不访问数据库,这几乎是不可能的。
  3. 反馈将不胜感激。我想确保我的系统安全。 :)

    谢谢!

3 个答案:

答案 0 :(得分:6)

好的,这就是...... 不要滚动你自己的安全性。以下是一些问题:

  1. 散列密码存储为cookie。 这与存储/传递普通文本密码没有什么不同,因为它是在没有应用散列函数功能的情况下验证的。

  2. Cookie是SQL注入攻击媒介。

  3. 使用SHx进行散列。 (使用bcrypt,scrypt,hmac等)

  4. 然后我停止了寻找。 #1表明这应留给现有的经过测试/审查的库。

答案 1 :(得分:1)

使用hash_hmac

我这样使用它:hash_hmac($ algo,$ password。$ salt,$ siteKey);

即使攻击者进入您的数据库,他们也需要您的sitekey以便成功地进行暴力破解,但我不会对碰撞发表评论。选择你的算法/毒药。 :d

答案 2 :(得分:1)

盐腌给你额外的安全性吗?是。如果散列被破坏,你需要更多的资源来破解密码,因为salt增加了很多组合。所以现在你不能使用旧的传统rainbow table攻击。在哪里储存盐是不同的问题。通常黑客会检索哈希值?通过妥协数据库。如果数据库受到损害,那么他也将拥有盐,这使盐析效率降低。但是如果在脚本中对salt进行硬编码,那么妥协数据库就不会产生影响。所以我强烈考虑在脚本中硬编码盐或使用两种盐 - 硬编码或在数据库中。

第二个问题。不要在密码中存储密码。您可以非常轻松地伪造它们(即使在chrome高级设置中)。或者窃取他们(例如XSS漏洞)。将它们存放在会话中。