Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/database/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 什么通过电子邮件获取用户并检查密码的代码有什么问题?_Php_Database - Fatal编程技术网

Php 什么通过电子邮件获取用户并检查密码的代码有什么问题?

Php 什么通过电子邮件获取用户并检查密码的代码有什么问题?,php,database,Php,Database,我是php的新手,我正在实现一个登录系统,在这个系统中,用户输入电子邮件和密码,并检查它们是否存在于数据库中(phpmyadmin中的mysql) 当用户首次注册时,使用此功能对密码进行加密: /** * Encrypting password * * @param * password * returns salt and encrypted password */ public function hashSSHA($password) {

我是php的新手,我正在实现一个登录系统,在这个系统中,用户输入电子邮件和密码,并检查它们是否存在于数据库中(phpmyadmin中的mysql)

当用户首次注册时,使用此功能对密码进行加密:

/**
 * Encrypting password
 *
 * @param
 *          password
 *          returns salt and encrypted password
 */
public function hashSSHA($password) {
    $salt = sha1 ( rand () );
    $salt = substr ( $salt, 0, 10 );
    $encrypted = base64_encode ( sha1 ( $password . $salt, true ) . $salt );
    $hash = array (
            "salt" => $salt,
            "encrypted" => $encrypted 
    );
    return $hash;
}
作为密码解密密钥的salt参数与用户信息一起存储在数据库中,解密代码为:

/**
 * Decrypting password
 *
 * @param
 *          salt, password
 *          returns hash string
 */
public function checkhashSSHA($salt, $password) {
    $hash = base64_encode ( sha1 ( $password . $salt, true ) . $salt );

    return $hash;
}
当我用输入的电子邮件和密码去取用户时,密码被解密

/**
 * Get user by email and password
 */
public function getUserByEmailAndPassword($email, $password) {
    $stmt = $this->conn->prepare ( "SELECT * FROM users WHERE email = ?" );

    $stmt->bind_param ( "s", $email );

    if ($stmt->execute ()) {
        $user = $stmt->get_result ()->fetch_assoc ();
        $stmt->close ();
        $salt = $user ["salt"];
        $hash = $this->checkhashSSHA ( $salt, $user ["encrypted_password"] );
        if ($hash == $password) {
            return $user;
        } else {
            return NULL;
        }
    } else {
        return NULL;
    }
}

问题是当用户输入正确的电子邮件和密码时,此代码仍然返回NULL,我怀疑处理密码部分有问题。

我建议您不要使用sshhash函数,而是查看php函数password\u verify()

在此处查看该功能和相关功能的文档:

问题在于这两行:

$hash = $this->checkhashSSHA ( $salt, $user ["encrypted_password"] );
if ($hash == $password) {
$hash = $this->checkhashSSHA ( $salt, $user ["encrypted_password"] );
if ($hash == $password) {
首先,您正在对已经散列的密码进行散列,而不是明文密码。
然后将“哈希中的哈希”与明文密码进行比较。
所以你在做
hash(hash(pw))==pw
,而它应该是
hash(pw)==hash(pw)

您只需交换
$user[“encrypted_password”]
$password

$hash = $this->checkhashSSHA ( $salt, $password );
if ($hash == $user ["encrypted_password"]) {

Siguza的回答是正确的,但是您对他的回答的评论反映了一种非常合理的混淆,因为
checkhashSSHA()
函数的名称有点误导(即,它的名称与其行为不匹配)。以“check”开头的函数名应返回布尔值。我建议改为:

/**
 * Decrypting password
 *
 * @param
 *          password, hash, salt
 *          returns boolean
 */
public function checkhashSSHA($password, $hash, $salt) {
    $hash2 = base64_encode ( sha1 ( $password . $salt, true ) . $salt );

    return ($hash == $hash2) ;
}
现在更改这两行:

$hash = $this->checkhashSSHA ( $salt, $user ["encrypted_password"] );
if ($hash == $password) {
$hash = $this->checkhashSSHA ( $salt, $user ["encrypted_password"] );
if ($hash == $password) {
关于这一行:

if (checkhashSSHA($password, $user["encrypted_password"], $salt)) {
现在它更清晰、更容易使用,而且它的行为与它的名称相匹配。但是,如果您希望增强代码中的命名,以下是一些建议:

  • checkhashSSHA()
    更改为
    comparehashsha()
  • 将数据库中的
    加密密码
    更改为
    哈希密码

更重要的是,sha1哈希算法有点陈旧,不太安全。我建议将其更改为更安全的散列,如sha512。查看并阅读Kai Petzke的评论,了解完整内容。

在上一个代码块中,您正在对哈希进行哈希运算,而不是明文密码。。。因此,您最终会将密码与散列的散列进行比较……请注意,您是在对密码进行散列,而不是对其进行“加密”。这并不能回答眼前的问题。+1,但只想为OP添加注释。出于安全原因,建议不要返回带有散列密码和salt的
$user
。没有其他代码需要这两个值,因此在返回
$user
@Siguza之前,请将它们设置为
null
。如果仔细观察,我不会对已经散列的内容进行散列。我正在调用checkhashSSHA,这是一个unhashing函数,它将加密密码作为文本返回并将其放入$hash中(我的错误是它不应该被称为hash)然后我将返回的内容与用户输入的$password进行比较是的,您不是在散列,您正在调用
checkhashSSHA()
…但是如果您仔细看,
checkhashSSHA()
正在使用
sha1()进行散列
函数。这就是Siguza的意思。这都是正确的,您正确地将其称为哈希,但您只需遵循此答案并交换变量,一切都会好起来。是的,您和@Siguza都是对的,我错过了一些东西……我的不好,谢谢你们的帮助。不客气。这不是您的错。函数的名称和行为函数具有误导性。有关详细信息,请参阅我的答案。