在数据库中存储密码的md5哈希值并进行比较

时间:2011-10-18 15:07:25

标签: php mysql security

在将数据插入数据库之前,我加密了用户名和密码,如下所示:

 $userName=strip_tags($userName);
  $pass=strip_tags($pass);

  $userName= htmlentities($userName, ENT_QUOTES, 'UTF-8');
  $pass= htmlentities($pass, ENT_QUOTES, 'UTF-8');


  $userName=mysql_real_escape_string($userName);
  $pass=mysql_real_escape_string($pass);


   $salt = 'SHIFLETT';
   $password_hash = md5($salt . md5($pass.$salt));

这样做是为了防止SQL攻击和一般SQL注入。

现在我想检查用户在登录时给我的传递和名称。我重复了相同的转义字符剥离和转义特殊字符的过程。 所以这是检查通行证的功能:

   function validateLogin($user_name, $pass)
   {
  $userName=strip_tags($userName);
  $pass=strip_tags($pass);

  $userName= htmlentities($userName, ENT_QUOTES, 'UTF-8');
  $pass= htmlentities($pass, ENT_QUOTES, 'UTF-8');


  $userName=mysql_real_escape_string($userName);
  $pass=mysql_real_escape_string($pass);


   $salt = 'SHIFLETT';
   $password_hash = md5($salt . md5($pass.$salt));

   $result=mysql_query("SELECT COUNT(*) AS Result FROM users WHERE user_name='$user_name' AND pass='$password_hash'");

   mysql_close();

   if($row=mysql_fetch_array($result))
   {
       if($row['Result']>0)
       {
           echo "Login successful";
       }
       else
       {
           echo "Login unsuccessful";
       }
   }
   }

我的问题是所有这些安全预防措施,验证工作?如果我在插入时使用相同的MD5编码然后在select语句上,MD5将返回相同的传递吗?

4 个答案:

答案 0 :(得分:3)

为了灵活性,您应该创建一个哈希(不加密)密码的函数。此外,使用比md5更强大的算法(如我的示例中使用的sha512)。

function hashPassword($str)
{
        return hash("sha512", $str . "salt");
}

我还建议使用mysql_real_escape_string

$password_hash = hashPassword($_POST['password']);
$username = mysql_real_escape_string($_POST['username']);

然后使用auto_incremented int并选择它。

mysql> create table users (
-> id int primary key auto_increment,
-> username varchar(20),
-> password char(128)); 

然后只需将返回的行与用户名和密码进行比较。

$check = "select id from users where username = '$username' and password = '$password_hash'";
$result = mysql_query($check);

if(mysql_num_rows($result))
{
    echo "<p>Login was successful!</p>\n";
}

回答你的问题:是的,将散列密码与数据库中的散列字符串进行比较是可行的。

答案 1 :(得分:2)

简短回答:是的,它会匹配

长/讲座答案:md5很弱,恒盐很差,在散列之前无需转义密码等。

答案 2 :(得分:1)

$pass=mysql_real_escape_string($pass);

相当多余。即使密码包含SQL元字符(例如'),在通过md5运行密码之后它仍然会消失。所有这一切都是为每个可逃避字符的密码字符串添加一个额外的字符,所以它是一种伪salting。

但是否则,是的......只要你对使用它们的地方的密码执行完全相同的md5 / salting过程,并且只在数据库中存储/比较结果哈希,那么你的比较将是有效的。 / p>

答案 3 :(得分:0)

这个问题有些陈旧,但现在有更好的替代方案,使用php 5.5。不再需要上面的代码。 PHP 5.5允许轻松创建内置的密码保护。这几乎是愚蠢的证据。 http://www.php.net/manual/en/function.password-hash.php正如您所看到的那样只需使用

password_hash("yourpass", PASSWORD_DEFAULT)

您同时使用随机盐和bcrypt。如果您还没有更新到最新版本的PHP,我建议您现在这样做。