盐渍密码?

时间:2014-04-16 22:02:29

标签: php mysql

我有一个工作注册和登录脚本,但我想对密码加密,以确保它们能够抵御黑客和SQL注入

我该怎么做? 这是我的代码如下; 谢谢 HTML

<form method="post">
        <input type="text" name="newUsername" placeholder="Username"/>
        <input type="password" name="newPassword" placeholder="Password"/>
        <input type="submit" name="signUp" value="Sign Up!"/>
</form>
<form method="post">
    <input type="text" name="Username" placeholder="Username"/>
    <input type="password" name="Password" placeholder="Password"/>
    <input type="submit" name="LogIn" value="Log In"/>
</form>

然后PHP:

if($_POST['signUp']) {
    $username = $_POST['newUsername'];
    $pass = $_POST['newPassword'];
    $signedUp = SignUp($Username,$pass);
    echo $signUpCode[$signedUp]; // See the SignUp function in prefunc.php

} elseif($_POST['LogIn']) {
    $username = $_POST['Username'];
    $password = $_POST['Password'];
    $loggedIn = LogIn($username,$password);
    echo $logInCode[$loggedIn];

}

$signUpCode = Array(
    "-3"=>"Logged in already - can't sign up!",
    "-2"=>"Username already exists!",
    "-1"=>"Failed to sign up - please try again!",
    "1"=>"Signed up, and logged in successfully!"
);

function SignUp($Username,$Password) { 
    $Username = preg_replace("/[^a-zA-Z0-9]/","",$Username);
    $u = mysql_query("SELECT * FROM Users WHERE LOWER(Username)=LOWER('$Username')");

    if(getCurrentId()){
        return -3;
    }

    if(!mysql_num_rows($u)) {
        mysql_query("INSERT INTO Users SET Username='$Username',Password=''$Password") or die(mysql_error());
        $u = mysql_query("SELECT * FROM Users WHERE LOWER(Username)=LOWER('$Username')");

    if(mysql_num_rows($u)) {
        LogIn($Username,$Password);
        return 1;
    } else {
        return -1;
    }
}

return -2;

}

1 个答案:

答案 0 :(得分:1)

几点说明:

  • 您需要考虑将password_hash()password_verify()用于此目的。这些是PHP中用于密码散列的最佳“开箱即用”功能

用法示例:

$password_hash = password_hash($password, PASSWORD_DEFAULT);
$query = "INSERT INTO users (Username, Password) VALUES ('{$username}', '{$password_hash}')";
  • 在尝试插入用户之前,应该没有任何理由首先检查用户是否存在。只要您的“用户名”字段上有唯一索引,如果它是重复的用户名,则插入将失败。每次尝试创建用户时,这都可以为您的数据库节省额外的查询。您也不应该向用户发送已存在用户名的消息,因为这是一种糟糕的安全措施。用户插入查询应该成功或失败,对于因插入重复键而导致失败的情况,您不应该在意。
  • 您不应该使用mysql_*功能。这是不推荐使用的功能。使用mysqliPDO
  • 使用mysqliPDO时,您应该使用带有绑定参数的预准备语句。目前,您的代码需要进行SQL注入,因为在尝试在查询中使用它之前,您没有做任何事情来逃避用户输入。非常非常糟糕的做法。

使用参数化预准备语句,您的查询将类似于:

$query = "INSERT INTO users (Username, Password) VALUES (:username, :password_hash)";

然后您将准备并执行此操作。我不打算详细说明,因为网上有成千上万的例子如何做到这一点。