新的PHP应用程序 - 保存和保护用户密码

时间:2011-01-01 21:16:16

标签: php

我正在设置一个新的PHP应用程序,并希望学习盐和安全的用户密码。我不确定注册过程中需要执行此操作的步骤。另外,我是否还需要更改登录表单?

    if(isset($_POST['submit'])){
        //protect and then add the posted data to variables
        $username = protect($_POST['username']);
        $password = protect($_POST['password']);
        $passconf = protect($_POST['passconf']);
        $email = protect($_POST['email']);
        //check to see if any of the boxes were not filled in
        if(!$username || !$password || !$passconf || !$email){
            //if any weren't display the error message
            echo "<center>You need to fill in all of the required filds!</center>";
        }else{
            //if all were filled in continue checking
            //Check if the wanted username is more than 32 or less than 3 charcters long
            if(strlen($username) > 32 || strlen($username) < 3){
                //if it is display error message
                echo "<center>Your <b>Username</b> must be between 3 and 32 characters long!</center>";
            }else{
                //if not continue checking
                //select all the rows from out users table where the posted username matches the username stored
                $res = mysql_query("SELECT * FROM `users` WHERE `username` = '".$username."'");
                $num = mysql_num_rows($res);
                //check if theres a match
                if($num == 1){
                    //if yes the username is taken so display error message
                    echo  "<center>The <b>Username</b> you have chosen is already taken!</center>";
                }else{
                    //otherwise continue checking
                    //check if the password is less than 5 or more than 32 characters long
                    if(strlen($password) < 5 || strlen($password) > 32){
                        //if it is display error message
                        echo "<center>Your <b>Password</b> must be between 5 and 32 characters long!</center>";
                    }else{
                        //else continue checking
                        //check if the password and confirm password match
                        if($password != $passconf){
                            //if not display error message
                            echo "<center>The <b>Password</b> you supplied did not math the confirmation password!</center>";
                        }else{
                            //otherwise continue checking
                            //Set the format we want to check out email address against
                            $checkemail = "/^[a-z0-9]+([_\\.-][a-z0-9]+)*@([a-z0-9]+([\.-][a-z0-9]+)*)+\\.[a-z]{2,}$/i";
                            //check if the formats match
                            if(!preg_match($checkemail, $email)){
                                //if not display error message
                                echo "<center>The <b>E-mail</b> is not valid, must be name@server.tld!</center>";
                            }else{
                                //if they do, continue checking
                                //select all rows from our users table where the emails match
                                $res1 = mysql_query("SELECT * FROM `users` WHERE `email` = '".$email."'");
                                $num1 = mysql_num_rows($res1);
                                //if the number of matchs is 1
                                if($num1 == 1){
                                    //the email address supplied is taken so display error message
                                    echo "<center>The <b>E-mail</b> address you supplied is already taken</center>";
                                }else{
                                    //finally, otherwise register there account
                                    //time of register (unix)
                                    $registerTime = date('U');
                                    //make a code for our activation key
                                    $code = md5($username).$registerTime;
                                    //insert the row into the database
                                    $res2 = mysql_query("INSERT INTO `users` (`username`, `password`, `email`, `rtime`) VALUES('".$username."','".$password."','".$email."','".$registerTime."')");
                                    //send the email with an email containing the activation link to the supplied email address

3 个答案:

答案 0 :(得分:3)

你绝对必须阅读这篇文章:Enough with the rainbow tables

总结:如果你没有使用BCrypt,那你做错了。不,如果没有,但没有。 (这也意味着使用MD5或SHA-1或SHA-512或其他任何建议的所有建议都是错误的。)

答案 1 :(得分:0)

至于你何时这样做,应该在你将它插入数据库之前的某个时候,但在你检查它是否有错误之后。

虽然有些建议。

而不是在错误检查期间嵌套ifs,以便在用户名失败时,密码不会被检查,如果密码失败,则不会检查passconf尝试类似这样的事情:

$errors = array();

if(strlen($username) > 32 || strlen($username) < 3)
{
     $errors['username'] = "Username must be between 3 and 32 characters.";
}
else
{
     $res = mysql_query("SELECT * FROM `users` WHERE `username` = '".$username."'");
     $num = mysql_num_rows($res);
     if($num == 1)
     {
          $errors['username'] = "Username already exists!";
     }
}

if(strlen($password) < 5 || strlen($password) > 32)
{
    $errors['password'] = "Password must be between 5 and 32 characters.";
}
else if($password != $confpass)
{
    $errors['password'] = "Passwords do not match.";
}

等。等等,以便检查每个字段,如果有,则返回错误。然后你在最后做这样的事情:

if(!count($errors))  //or if(count($errors) == 0)
{
     //code to process login/registration/whatever  Do password hashing here.
}
else
{
     //There were errors, do something else
}

通过这种方式,您可以获得所有错误,因此您可以立即告诉用户输入的所有内容,并且代码没有深度嵌套。

此外,对于上面使用的哈希算法进行火焰战争的人,除非您尝试创建美国政府或公司应用程序,否则请忽略它们。除非您的应用程序受到足够的欢迎以保证攻击,否则攻击者不会非常关心实际攻击。以某种方式对它进行散列非常重要。

答案 2 :(得分:0)

安全很难。不要自己做,但让出口搞清楚。你可以阅读那些规格/实现(如果打开):

  • 的OpenID
  • google friend connect
  • facebook connect
  • twitter单点登录

仅举几个选项。