从sha1加盐密码认证用户登录

4
我有一个非常简单的登录/用户注册脚本,使用sha1和盐存储密码。我已经成功地实现了密码和用户创建,并将所有内容存储在数据库中,但是当我尝试使用凭据登录时,它却无法工作。我似乎找不到任何关于此主题的信息。
以下是我的添加用户表单:
session_start();
include("includes/resume.config.php");

// make sure form fields have a value and strip them
function check_input($data, $problem='')
{
$data = trim($data);
$data = stripslashes($data);
$data = htmlspecialchars($data);
if ($problem && strlen($data) == 0)
{
    die($problem);
}
    return $data;
}

// get form values, escape them and apply the check_input function
$name = $link->real_escape_string(check_input($_POST['name'], "Please enter a name!"));
$email = $link->real_escape_string(check_input($_POST['email'], "Please enter an email!"));
$password = $link->real_escape_string(check_input($_POST['password'], "Please enter a password!"));

// generate a random salt for converting passwords into MD5
$salt = bin2hex(mcrypt_create_iv(32, MCRYPT_DEV_URANDOM));
$saltedPW =  $password . $salt;
$hashedPW = sha1($saltedPW);

mysqli_connect($db_host, $db_user, $db_pass) OR DIE (mysqli_error());
// select the db
mysqli_select_db ($link, $db_name) OR DIE ("Unable to select db".mysqli_error($db_name));

 // our sql query
$sql = "INSERT INTO admins (name, email, password, salt) VALUES ('$name', '$email', '$hashedPW', '$salt');";

//save the updated information to the database          
mysqli_query($link, $sql) or die("Error in Query: " . mysqli_error($link));

if (!mysqli_error($link)) 
{
    header("Location: file_insert.php");
}   

这是我的登录脚本:问题出在这里

function check_input($data, $problem='')
{
$data = trim($data);
$data = stripslashes($data);
$data = htmlspecialchars($data);
if ($problem && strlen($data) == 0)
{
    die($problem);
}
    return $data;
}

if(isset($_POST['submitLogin'])) { //form submitted?

// get form values, escape them and apply the check_input function
$name = $link->real_escape_string(check_input($_POST['name'], "Please enter a name!"));
$password = $link->real_escape_string(check_input($_POST['password'], "Please enter a password!"));

$saltQuery = $link->query('SELECT salt FROM admins WHERE name = "'.$name.'"');

$salt = mysqli_fetch_assoc($saltQuery);
$saltedPW =  $password . $salt;
$hashedPW = sha1($saltedPW);

mysqli_connect($db_host, $db_user, $db_pass) OR DIE (mysqli_error());
// select the db
mysqli_select_db ($link, $db_name) OR DIE ("Unable to select db".mysqli_error($db_name));

$validate_user = $link->query('SELECT id, name, password FROM admins WHERE name = "'.$name.'" AND password = "'.$hashedPW.'"');

if ($validate_user->num_rows == 1) {
    $row = $validate_user->fetch_assoc();
    $_SESSION['id'] = $row['id'];
    $_SESSION['loggedin'] = TRUE;
    Header('Location: file_insert.php');
} else {
    print "<center><p style='margin-top: 200px; font-weight: bold;'>Invalid Login Information</p>";
    print "<a href='admin-login.php'>Click here</a> to return to the login page.</center>";
}
}
2个回答

3
可能出现了更多问题,但肯定有一个原因是因为mysqli_fetch_assoc返回的是一个数组,而你却像使用字符串一样使用它。
当你调用$password . $salt时,PHP会抱怨数组转换成字符串,因为此时$salt是一个数组。结果是你得到了单词Array附加在密码上,导致哈希值不正确。如果你在php.ini中关闭了display_errors和/或设置了error_reporting以隐藏通知,则看不到此消息。
如果你改变:

$saltedPW =  $password . $salt;

to:

$saltedPW =  $password . $salt['salt'];

然后它应该就能工作了。

另外,您应该在将$salt插入数据库之前进行转义,因为它可能包含null、不可打印或单/双引号,因为它是随机生成的。


那我应该把 $salt = mysqli_fetch_assoc($saltQuery); 改成 $salt = $saltQuery; 吗? - Ty Bailey
不,你仍然需要执行查询,保留那部分不变,只需按答案所示更改赋值即可。 - drew010
此外,如果您在查询中选择密码哈希和盐,则无需进行两个查询即可知道登录是否有效。如果找到匹配项,只需在 PHP 中对密码进行哈希处理并将其与已从数据库中选择的哈希密码进行比较即可。 - drew010

0

你没有说你是否收到任何错误信息,但从你发布的内容来看,我认为这是一个连接问题:

if(isset($_POST['submitLogin'])) { //form submitted?

// Here, you didn't connect to database, but you are expecting to fetch salt!
$saltQuery = $link->query('SELECT salt FROM admins WHERE name = "'.$name.'"');

$salt = mysqli_fetch_assoc($saltQuery);

因此,您可能需要首先连接到数据库:

if(isset($_POST['submitLogin'])) { //form submitted?

mysqli_connect($db_host, $db_user, $db_pass) OR DIE (mysqli_error());
// select the db
mysqli_select_db ($link, $db_name) OR DIE ("Unable to select db".mysqli_error($db_name));

// Here, you didn't connect to database, but you are expecting to fetch salt!
$saltQuery = $link->query('SELECT salt FROM admins WHERE name = "'.$name.'"');

其次,mysqli_fetch_assoc返回一个数组,其中键名为您在SELECT查询中嵌入的字段名称,最终代码应该像这样:

if(isset($_POST['submitLogin'])) { //form submitted?

mysqli_connect($db_host, $db_user, $db_pass) OR DIE (mysqli_error());
// select the db
mysqli_select_db ($link, $db_name) OR DIE ("Unable to select db".mysqli_error($db_name));

// Here, you didn't connect to database, but you are expecting to fetch salt!
$saltQuery = $link->query('SELECT salt FROM admins WHERE name = "'.$name.'"');
$salt = mysqli_fetch_assoc($saltQuery);
$saltedPW =  $password . $salt["salt"];
$hashedPW = sha1($saltedPW);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接