簡體   English   中英

通過電子郵件獲取用戶並檢查密碼的代碼有什么問題?

[英]What;s wrong with code which is getting user by email and checking for the 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,我懷疑處理密碼部分有問題。

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) {

到這一行:

if (checkhashSSHA($password, $user["encrypted_password"], $salt)) {

現在,它更清晰,更易於使用,並且其行為與其名稱匹配。 但是,如果您想增強代碼中的命名,請參考以下建議:

  • checkhashSSHA()更改為compareHashSSHA()
  • 更改encrypted_password在數據庫中hashed_password

更重要的是,sha1哈希算法有點陳舊,也不是很安全。 我建議將其更改為更安全的哈希,例如sha512。 檢查此內容,並閱讀Kai Petzke的評論全文。

問題在於這兩行:

$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"]) {

我建議您不要使用sshhash函數,而是查看php函數password_verify()

在此處查看有關該功能和相關功能的文檔: http : //php.net/manual/zh/function.password-verify.php

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM