如何使用PHP更改数据库中的SALT密码? [英] How to change a SALT password in a database using PHP?

查看:116
本文介绍了如何使用PHP更改数据库中的SALT密码?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用从android到某些php脚本的HTTP POST,以更新数据库中的用户密码.

我使用的SALT哈希与用户创建帐户并且数据库更新正在运行并更改SALT的值时使用的SALT哈希相同,但是当我尝试使用新密码登录时,这是不正确的.

用于创建密码的初始代码为:

public function storeUser($name, $email, $password, $rand) {
    $uuid = uniqid('', true);
    $hash = $this->hashSSHA($password);
    $encrypted_password = $hash["encrypted"]; // encrypted password
    $salt = $hash["salt"]; // salt
    $auth = 0;
    $result = mysql_query("INSERT INTO users(unique_id, authorized, auth_code, name, email, encrypted_password, salt, created_at) VALUES('$uuid', '$auth', '$rand', '$name', '$email', '$encrypted_password', '$salt', NOW())");
    // check for successful store
    if ($result) {
        // get user details 
        $uid = mysql_insert_id(); // last inserted id
        $result = mysql_query("SELECT * FROM users WHERE uid = $uid");
        // return user details
        return mysql_fetch_array($result);
    } else {
        return false;
    }
}

哈希函数是:

 /**
 * 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;
}

/**
 * Decrypting password
 * @param salt, password
 * returns hash string
 */
public function checkhashSSHA($salt, $password) {

    $hash = base64_encode(sha1($password . $salt, true) . $salt);

    return $hash;
}

最后是更新功能(问题出在哪里):

 /**
 * Updating a users
 * password
 */
public function updatePassword($email, $password) {
    $uuid = uniqid('', true);
    $hash = $this->hashSSHA($password);
    $encrypted_password = $hash["encrypted"]; // encrypted password
    $salt = $hash["salt"]; // salt

    $result = mysql_query("UPDATE users SET encrypted_password='$encrypted_password',  updated_at = NOW() WHERE email='$email'");
    $result = mysql_query("UPDATE users SET salt='$salt',  updated_at = NOW() WHERE email='$email'");


    // check for successful store
    if ($result) {
        // get user details
        $uid = mysql_insert_id(); // last inserted id
        $result = mysql_query("SELECT * FROM users WHERE email = '$email'");
        // return user details
        return mysql_fetch_array($result);
    } else {
        return false;
    }
}

一如既往,任何帮助都将不胜感激.

根据要求登录功能:

 /**
 * Get user by email and password
 */
public function getUserByEmailAndPassword($email, $password) {
    $result = mysql_query("SELECT * FROM users WHERE email = '$email'") or die(mysql_error());
    // check for result
    $no_of_rows = mysql_num_rows($result);
    if ($no_of_rows > 0) {
        $result = mysql_fetch_array($result);
        $salt = $result['salt'];
        $encrypted_password = $result['encrypted_password'];
        $hash = $this->checkhashSSHA($salt, $password);
        // check for password equality
        if ($encrypted_password == $hash) {
            // user authentication details are correct
            return $result;
        }
    } else {
        // user not found
        return false;
    }
}

解决方案

您建立了一个弱方案来对密码进行哈希处理,因为您使用了SHA1的单个迭代作为哈希函数,并且盐被截断为10个字符,并且是使用不安全的密码rand()函数生成的.然后,将盐储存在单独的区域中,会使您的生活变得更加艰难.

在您的情况下,我强烈建议您使用新功能 password_hash()和PHP的 password_verify() BCrypt哈希.它们负责安全随机盐的生成,结果字符串包含哈希值和盐,因此您可以将其存储在数据库的单个字段中.对于早期的PHP版本,存在一个兼容性包.

>

使用此功能的最简单方法是:

$hashToStoreInDb = password_hash($password, PASSWORD_BCRYPT);
$isPasswordCorrect = password_verify($password, $existingHashFromDb);

回答您的问题:我看不出它为什么不起作用的明显原因,通常问题是数据库字段太短.在您的情况下,您需要放置一个添加了10个字符的盐的二进制SHA1,该盐以base64_encoded编码(难以预测所需的大小).将SHA1中的二进制字符串(空字节)与普通字符串组合在一起也很危险.

I am using a HTTP POST from android to some php script in order to update a users password in the database.

I am using the same SALT hash as is done when the user creates the account and the database update is running and changing the values of SALT however when I try to log in with the new password it is coming as incorrect.

The initial code for creating the password is:

public function storeUser($name, $email, $password, $rand) {
    $uuid = uniqid('', true);
    $hash = $this->hashSSHA($password);
    $encrypted_password = $hash["encrypted"]; // encrypted password
    $salt = $hash["salt"]; // salt
    $auth = 0;
    $result = mysql_query("INSERT INTO users(unique_id, authorized, auth_code, name, email, encrypted_password, salt, created_at) VALUES('$uuid', '$auth', '$rand', '$name', '$email', '$encrypted_password', '$salt', NOW())");
    // check for successful store
    if ($result) {
        // get user details 
        $uid = mysql_insert_id(); // last inserted id
        $result = mysql_query("SELECT * FROM users WHERE uid = $uid");
        // return user details
        return mysql_fetch_array($result);
    } else {
        return false;
    }
}

The hashing functions are:

 /**
 * 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;
}

/**
 * Decrypting password
 * @param salt, password
 * returns hash string
 */
public function checkhashSSHA($salt, $password) {

    $hash = base64_encode(sha1($password . $salt, true) . $salt);

    return $hash;
}

And finally the update function (where the problem is):

 /**
 * Updating a users
 * password
 */
public function updatePassword($email, $password) {
    $uuid = uniqid('', true);
    $hash = $this->hashSSHA($password);
    $encrypted_password = $hash["encrypted"]; // encrypted password
    $salt = $hash["salt"]; // salt

    $result = mysql_query("UPDATE users SET encrypted_password='$encrypted_password',  updated_at = NOW() WHERE email='$email'");
    $result = mysql_query("UPDATE users SET salt='$salt',  updated_at = NOW() WHERE email='$email'");


    // check for successful store
    if ($result) {
        // get user details
        $uid = mysql_insert_id(); // last inserted id
        $result = mysql_query("SELECT * FROM users WHERE email = '$email'");
        // return user details
        return mysql_fetch_array($result);
    } else {
        return false;
    }
}

As always any help greatly appreciated.

EDIT:

Login function as requested:

 /**
 * Get user by email and password
 */
public function getUserByEmailAndPassword($email, $password) {
    $result = mysql_query("SELECT * FROM users WHERE email = '$email'") or die(mysql_error());
    // check for result
    $no_of_rows = mysql_num_rows($result);
    if ($no_of_rows > 0) {
        $result = mysql_fetch_array($result);
        $salt = $result['salt'];
        $encrypted_password = $result['encrypted_password'];
        $hash = $this->checkhashSSHA($salt, $password);
        // check for password equality
        if ($encrypted_password == $hash) {
            // user authentication details are correct
            return $result;
        }
    } else {
        // user not found
        return false;
    }
}

解决方案

You have built a weak scheme to hash your passwords, because you use a single iteration of SHA1 as hash function, and because the salt is truncated to 10 characters and is generated with the cryptographically unsafe rand() function. Then you make your life harder than necessary with storing the salt in a separate field.

In your case i would strongly recommend to use the new functions password_hash() and password_verify() of PHP to get a strong BCrypt hash. They take care of the generation of a safe random salt, and the resulting string contains the hash-value as well the salt, so you can store it in a single field in your database. There exists a compatibilty pack for earlier PHP versions.

The easiest way to use this functions will be:

$hashToStoreInDb = password_hash($password, PASSWORD_BCRYPT);
$isPasswordCorrect = password_verify($password, $existingHashFromDb);

To answer your question: I couldn't see an obvious reason why it doesn't work, often the problem is a database field that is too short. In your case you need place for a binary SHA1 with a 10 character salt added, that is base64_encoded (difficult to predict the necessary size). It can also be dangerous to combine the binary string from SHA1 (null bytes) with a normal string.

这篇关于如何使用PHP更改数据库中的SALT密码?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆