【问题标题】:How to reset password,Salt如何重设密码,盐
【发布时间】:2019-12-09 07:12:29
【问题描述】:

我有一些 php 脚本可以让我的用户使用电子邮件创建帐户。然后他设置了一个经过哈希处理的密码,并生成了一个盐并将其存储在我的数据库中。现在我正在重置密码,它工作正常,但新密码(更改密码,即使它正确无法验证电子邮件,因为注册时使用了盐和哈希)

下面是我用来加密user_password的Hash函数

public function hashFunction($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;
}

这是我的重置密码(更改密码但更改密码无法验证)

<?php
    if(isset($_POST["reset-password"])) {
        require_once('connect.php');
        $sql = "UPDATE `oasisdb`.`registration_data` SET `user_password` = '" . ($_POST["user_password"]). "' WHERE `registration_data`.`name` = '" . $_GET["name"] . "'";
        $result = mysqli_query($con,$sql);
        $success_message = "Password is reset successfully.";

    }
?>
<link href="demo-style.css" rel="stylesheet" type="text/css">
<script>
function validate_password_reset() {
    if((document.getElementById("user_password").value == "") && (document.getElementById("confirm_password").value == "")) {
        document.getElementById("validation-message").innerHTML = "Please enter new password!"
        return false;
    }
    if(document.getElementById("user_password").value  != document.getElementById("confirm_password").value) {
        document.getElementById("validation-message").innerHTML = "Both password should be same!"
        return false;
    }

    return true;
}
</script>
<form name="frmReset" id="frmReset" method="post" onSubmit="return validate_password_reset();">
<h1>Reset Password</h1>
    <?php if(!empty($success_message)) { ?>
    <div class="success_message"><?php echo $success_message; ?></div>
    <?php } ?>

    <div id="validation-message">
        <?php if(!empty($error_message)) { ?>
    <?php echo $error_message; ?>
    <?php } ?>
    </div>

    <div class="field-group">
        <div><label for="Password">Password</label></div>
        <div>
        <input type="password" name="user_password" id="user_password" class="input-field"></div>
    </div>

    <div class="field-group">
        <div><label for="email">Confirm Password</label></div>
        <div><input type="password" name="confirm_password" id="confirm_password" class="input-field"></div>
    </div>

    <div class="field-group">
        <div><input type="submit" name="reset-password" id="reset-password" value="Reset Password" class="form-submit-button"></div>
    </div>  
</form>

这是我的 mysql 表

CREATE TABLE `registration_data` (
  `id` int(255) NOT NULL,
  `name` varchar(150) NOT NULL,
  `email` varchar(150) NOT NULL,
  `user_password` varchar(80) NOT NULL,
  `salt` varchar(10) NOT NULL,
  `gender` varchar(50) NOT NULL,
  `phone` varchar(50) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

最后这是我的 login.php

<?php
require_once 'update_user_info.php';
$db = new update_user_info();

// json response array
$response = array("error" => FALSE);

if (isset($_POST['email']) && isset($_POST['password'])) {

       // receiving the post params
        $email = $_POST['email'];
        $password = $_POST['password'];

        // get the user by email and password
        $user = $db->VerifyUserAuthentication($email, $password);

        if ($user != false) {
            // use is found
            $response["error"] = FALSE;        
            $response["user"]["name"] = $user["name"];
            $response["user"]["email"] = $user["email"];
            $response["user"]["phone"] = $user["phone"];
            $response["user"]["gender"] = $user["gender"];
            echo json_encode($response);
        } else {
            // user is not found with the credentials
            $response["error"] = TRUE;
            $response["error_msg"] = "Wrong E-mail or Password. Please try again!";
            echo json_encode($response);
        }
    } else {
        // required post params is missing
        $response["error"] = TRUE; 
        $response["error_msg"] = "Required parameters E-mail and Password is missing!";
        echo json_encode($response);
    }
?>

这是在注册时使用哈希的方式

public function StoreUserInfo($name, $email, $password, $gender, $phone) {
        $hash = $this->hashFunction($password);
        $user_password = $hash["encrypted"]; // encrypted password
        $salt = $hash["salt"]; // salt

        $stmt = $this->conn->prepare("INSERT INTO registration_data(name, email, user_password, salt, gender, phone) VALUES(?, ?, ?, ?, ?, ?)");
        $stmt->bind_param("ssssss", $name, $email, $user_password, $salt, $gender, $phone);
        $result = $stmt->execute();
        $stmt->close();

【问题讨论】:

  • 你在哪里使用函数来散列你的密码?第二次使用请声明更新/选择的方法或为不冒 SQL 注入的风险进行任何查询
  • 更新了我的问题以适应注册时如何使用散列

标签: php mysql


【解决方案1】:

这是我用于密码重置页面的代码。
这包括密码强度验证。
也许这会对你有所帮助,你可以免费使用它。
您应该自己将其与您的代码合并。
我正在使用base64 编码的字符串来输入用户信息,例如什么电子邮件地址以及它是否是有效代码。

<meta charset="UTF-8">
<?php
require("mysql_config.php");
session_start();
$melding = "";
if (isset($_GET['usr']))
{
    $passwordresetcode = base64_decode($_GET['usr']);
}
else
{
    $passwordresetcode = '';
}
$strings = explode(', ', $passwordresetcode);

$email = $strings[0];
$code = $strings[1];

if(isset($_POST['resetpass'])){


     $query_login = " 
        UPDATE users SET 
        salt = :salt,
        password = :password
        WHERE email = '".$email."'
    "; 
    $salt = dechex(mt_rand(0, 2147483647)) . dechex(mt_rand(0, 2147483647)); 
    $password = $_POST['password'];
    $query_params = array( 
            ':salt' => $salt, 
            ':password' => hash('sha256', $password . $salt)
        ); 

    try {  
        $stmt11 = $db->prepare($query_login); 
        $result = $stmt11->execute($query_params); 
    } 
    catch(PDOException $ex){ die("Failed to run query 2: " . $ex->getMessage()); }
    header("Location: login.php"); /* Redirect browser */ 
}
else{

$code = str_replace(' ', '', $code);
//$code = trim($code," ");
$stmt = $db->prepare("  
SELECT  *
FROM    users 
WHERE   email = '$email'
 ");
$stmt->execute();
$row = $stmt->fetch(PDO::FETCH_ASSOC);  

if ($row)
{
    ?>  
    <link href="./bootstrap/css/bootstrap.min.css" rel="stylesheet" type="text/css" />
    <link rel="stylesheet" type="text/css" href="//fonts.googleapis.com/css?family=Open+Sans" />

    <div id="password_reset_form" class="col-X-6 col-xs-12" style="margin: 0 auto;">
   <h2>New password</h2>
    <form method="POST">
        <input type="password" id="pwd" name="password" minlength='8' autocomplete="off" placeholder="Password">
        <div id="progress">
          <div id="progress-bar"></div>
        </div> 
        <input type="password" id="repeat_pwd" name="repeatpassword" minlength='8' autocomplete="off" placeholder="Repeat Password">
        <div id="match" style="background: lightblue;">

        </div><br/>   
        <input type="submit" disabled id="resetpassword"  onclick="hide_form()" name="resetpass" class="button disabled" value="Verstuur">
        <br/><br/>
    </form>

    </div>

    <?php
    }
}
else{
echo 'No user found!';
}

?>
<script>
function hide_form(){
    $('#password_reset_form').css( "display", "none" );
}
function check(score){
  if($("#pwd").val() == $("#repeat_pwd").val()){
    $("#match").html("Passwords do not match!");
    $("#match").css("background-color", "#DFF2BF");
    if(score == 5){$("#resetpassword").prop('disabled', false); $("#resetpassword").removeClass("disabled");}else{$("#resetpassword").prop('disabled', true); $("#resetpassword").addClass("disabled"); $("#match").html("Password not strong enough!"); $("#match").css("background-color", "rgb(255, 182, 119)");}
  }
  else{
    $("#match").html("Passwords do not match!");
    $("#match").css("background-color", "#FFBABA");
   $("#resetpassword").prop('disabled', true);
 $("#resetpassword").addClass("disabled");  
  }
}
    var score = 0;
    function update_bar( element, password ) {
        var desc = [{'width':'0px'}, {'width':'20%'}, {'width':'40%'}, {'width':'60%'}, {'width':'80%'}, {'width':'100%'}];
        var descClass = ['', 'progress-bar-danger', 'progress-bar-danger', 'progress-bar-warning', 'progress-bar-warning', 'progress-bar-success'];
        score = 0;
        element.removeClass();
        if(password.length > 10) {
            score++;
        }
        if(password.length > 6) {
            score++;
        }
        if ( (password.match(/[a-z]/)) && (password.match(/[A-Z]/))) {
            score++;
        }
        if (password.match(/\d+/)) {
            score++;
        }
        if (password.match(/.[/,\\,!,@,#,$,%,^,&,*,?,_,~,-,(,)]/)) {
            score++;
        }
        if (password.length > 8) {
            score++;
        }
        if(score > 5){
            score = 5;
        }

        element.addClass( descClass[score] );
        element.css( desc[score] );
       check(score);     
    }

  $("#pwd").keyup(function() {
     update_bar( $( "#progress-bar" ), $("#pwd").val() );

   });
$("#pwd").bind('paste', function(event) { 
     update_bar( $( "#progress-bar" ), $("#pwd").val() );         
}); 

$("#pwd").bind('change', function(event) { 
     update_bar( $( "#progress-bar" ), $("#pwd").val() );         
});     


$("#repeat_pwd").keyup(function() {
     check(score);     

   });
$("#repeat_pwd").bind('paste', function(event) { 
     check(score);            
}); 

$("#repeat_pwd").bind('change', function(event) { 
     check(score);              
});     




</script>


<style>
form {
  max-width: 400px;
  padding: 1em;
}
    h2{
        text-align: center;
        vertical-align: middle;
    }
input {
  display: block;
  width: 100%;
  box-sizing: border-box;
  padding: 6px;
  border: 1px solid #ddd;
}

#progress {
  height: 5px;
    border: 1px solid #ddd;
  margin-bottom: 10px;
}

#progress-bar {
  width: 0%;
  height: 100%;
  transition: width 500ms linear;
}
#match{
  height: 30px;
  margin-top: 10px;
  border: 1px solid #ddd;
  font-family: "HelveticaNeue-Light", "Helvetica Neue Light", "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif; 
  font-weight: 300;
  border-radius: 3px 3px 3px 3px;
  line-height: 30px;
  text-align: center;
}

.progress-bar-danger {
  background: #d00;
}

.progress-bar-warning {
  background: #f50;
}

.progress-bar-success {
  background: #080;
}
    #password_reset_form{
        margin: 0 auto;
        display: table;
        margin-top: 40px;
    }
     #password_reset_form img{
        margin: 0 auto;
         display: table;

    }
      #password_reset_form form{
        margin: 0 auto;
         display: block;

    }

    body{
        font-family: 'Open Sans';
    }
</style>

【讨论】:

    【解决方案2】:

    使用 php,您可以使用这两个函数来获取密码的安全哈希,而无需将盐保存到数据库中:

    password_hash() : https://www.php.net/manual/fr/function.password-hash.php

    password_verify() : https://www.php.net/manual/fr/function.password-verify.php

    它非常易于使用并且比散列函数更短。我认为您可以使用此功能轻松重置密码,而不会在代码或数据库中出现加盐问题。

    【讨论】:

      猜你喜欢
      • 2012-09-25
      • 2011-05-09
      • 2013-02-28
      • 1970-01-01
      • 2012-07-04
      • 2014-10-31
      • 2012-07-07
      相关资源
      最近更新 更多