密码"盐" - 我做得对吗?

fru*_*cup 2 php mysql encryption session login

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

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

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

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

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

($ row是数据库中的fetched数组.$ 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; 
Run Code Online (Sandbox Code Playgroud)

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

  1. 欺骗一个我认为没有服务器访问权限的会话变量
  2. 使用加密密码+ salt欺骗cookie,我相信如果不访问数据库几乎是不可能的.

反馈将不胜感激.我想确保我的系统安全.:)

谢谢!

小智 6

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

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

  2. cookie是SQL注入攻击向量.

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

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

  • 要扩展#1,如果我要嗅探您的一个用户和您的网站之间的会话,并且他们选择了记住我的cookie,我现在有他们的用户名和哈希密码,所以我可以构建一个相同的cookie并自动以他们身份登录.除此之外没有安全检查,以确保具有有效cookie的人实际上是原始cookie的所有者. (2认同)
  • 为了记住我的功能,您不应将其密码存储为cookie.相反,生成GUID并将其另存为cookie +将其添加到数据库中.当用户明确注销时,从数据库中删除GUID.此外,这允许您通过删除相应的身份验证令牌,使用户能够注销他可能登录的其他会话 (2认同)