2014-03-13 73 views
2

我嘗試使用發佈的用戶密碼和來自數據庫的散列函數password_verify檢查密碼。password_verify php不匹配

首先,我是怎麼生成的密碼和散列:

$user_password = $this->generate_password(); 

private function generate_password($length = 8) 
{ 
$chars = "[email protected]#$%^&*()_-=+;:,.?"; 
$password = substr(str_shuffle($chars), 0, $length); 
return $password; 
} 

define("HASH_COST_FACTOR", "10"); 
$hash_cost_factor = (defined('HASH_COST_FACTOR') ? HASH_COST_FACTOR : null); 
$user_password_hash = password_hash($user_password, PASSWORD_DEFAULT, array('cost' => $hash_cost_factor)); 


$sql = "INSERT INTO users (user_name, user_password_hash, user_email, user_creation_timestamp) 
VALUES (:user_name, :user_password_hash, :user_email, :user_creation_timestamp)"; 
$query = $this->db->prepare($sql); 
$query->execute(array(':user_name' => $user_name, 
         ':user_password_hash' => $user_password_hash, 
         ':user_email' => $user_email, 
         ':user_creation_timestamp' => $user_creation_timestamp)); 
$count = $query->rowCount(); 
if ($count != 1) { 
    $_SESSION["feedback_negative"][] = FEEDBACK_ACCOUNT_CREATION_FAILED; 
return false; 
} 

    if ($this->sendUserpassword($user_email, $user_password)) { 
     $_SESSION["feedback_positive"][] = FEEDBACK_ACCOUNT_SUCCESSFULLY_CREATED; 
     return true; 
    } else { 
     $query = $this->db->prepare("DELETE FROM users WHERE user_id = :last_inserted_id"); 
     $query->execute(array(':last_inserted_id' => $user_id)); 
     $_SESSION["feedback_negative"][] = FEEDBACK_PASSWORD_MAIL_SENDING_FAILED; 
     return false; 
    } 
private function sendUserpassword($user_email, $user_password) 
{ 
    $mail = new PHPMailer; 

    if (EMAIL_USE_SMTP) { 
     $mail->IsSMTP(); 
     $mail->SMTPDebug = PHPMAILER_DEBUG_MODE; 
     $mail->SMTPAuth = EMAIL_SMTP_AUTH; 
     if (defined(EMAIL_SMTP_ENCRYPTION)) { 
      $mail->SMTPSecure = EMAIL_SMTP_ENCRYPTION; 
     } 
     $mail->Host = EMAIL_SMTP_HOST; 
     $mail->Username = EMAIL_SMTP_USERNAME; 
     $mail->Password = EMAIL_SMTP_PASSWORD; 
     $mail->Port = EMAIL_SMTP_PORT; 
     } else { 
     $mail->IsMail(); 
     } 

    $mail->From = EMAIL_PASSWORD_FROM_EMAIL; 
    $mail->FromName = EMAIL_PASSWORD_FROM_NAME; 
    $mail->AddAddress($user_email); 
    $mail->Subject = EMAIL_PASSWORD_SUBJECT; 
    $mail->Body = EMAIL_PASSWORD_CONTENT . '/' . $user_password; 

    if($mail->Send()) { 
    $_SESSION["feedback_positive"][] = FEEDBACK_PASSWORD_MAIL_SENDING_SUCCESSFUL; 
    return true; 
    } else { 
    $_SESSION["feedback_negative"][] = FEEDBACK_PASSWORD_MAIL_SENDING_ERROR . $mail->ErrorInfo; 
    return false; 
    } 
} 

驗證上登錄:

if (!isset($_POST['user_name']) OR empty($_POST['user_name'])) { 
    $_SESSION["feedback_negative"][] = FEEDBACK_USERNAME_FIELD_EMPTY; 
    return false; 
} 

if (!isset($_POST['user_password']) OR empty($_POST['user_password'])) { 
    $_SESSION["feedback_negative"][] = FEEDBACK_PASSWORD_FIELD_EMPTY; 
    return false; 
} 

$sth = $this->db->prepare("SELECT user_id, 
          user_name, 
          user_email, 
          user_password_hash, 
          user_active, 
          user_account_type 
          FROM users 
          WHERE (user_name = :user_name OR user_email = :user_name)"); 

$sth->execute(array(':user_name' => $_POST['user_name'], ':provider_type' => 'DEFAULT')); 
$count = $sth->rowCount(); 

if ($count != 1) { 
    $_SESSION["feedback_negative"][] = FEEDBACK_LOGIN_FAILED; 
    return false; 
}  

$result = $sth->fetch(); 

//check via password_verify 
if (password_verify($_POST['user_password'], $result->user_password_hash)) { 
    ... 
    return true; 
} else { 
    $_SESSION["feedback_negative"][] = FEEDBACK_PASSWORD_WRONG; 
    return false; 
} 

總是得到密碼錯誤的信息。我讀了這個php password_hash and password_verify issues no match,但我用手測試了這個哈希字符串來驗證字符串。

的hashstring: $ 2Y $ 10 $ SwSq7OukPpN/QJ8YOdKgquJQ28fQbNY1Q3JdTFnoe.2VxD/D2RXBS

通過電子郵件發送的密碼: /F)1C(-JG

手工測試:

$hash = '$2y$10$SwSq7OukPpN/QJ8YOdKgquJQ28fQbNY1Q3JdTFnoe.2VxD/D2RXBS'; 
$password = '/f)1c(-JG'; 

if (password_verify($password, $hash)) { 
    echo 'Password is valid!'; 
} else { 
    echo 'Invalid password.'; 
} 

打印無效的密碼

+1

是您的數據庫列長到足以存儲整個哈希未截斷? – deceze

+1

yes user_password_hash VARCHAR(255)COLLATE utf8_unicode_ci DEFAULT NULL – mnlfischer

+0

然後,您可以提供一個顯示問題的*最小*測試用例嗎?因爲'password_'的功能正常,並且*顯示爲正確使用它們。但是,有很多部分我們在這裏沒有看到並且無法調試。 – deceze

回答

1

您的$ hash變量在您的測試用例中是無效的,並且不符合passwo RD

$hash = '$2y$10$SwSq7OukPpN/QJ8YOdKgquJQ28fQbNY1Q3JdTFnoe.2VxD/D2RXBS'; 
$password = '/f)1c(-JG'; 

if (password_verify($password, $hash)) { 
echo 'Password is valid!'; 
} else { 
    echo 'Invalid password.'; 
} 

當我用這個代碼,一切正常

$password = '/f)1c(-JG'; 
$hash = password_hash($password, PASSWORD_DEFAULT, array("cost" => 10)); 

if (password_verify($password, $hash)) { 
    echo 'Password is valid!'; 
} else { 
    echo 'Invalid password.'; 
} 

我使用PHP 5.5.10

+0

有一個錯誤的smtp發送錯誤的密碼 – mnlfischer

+0

@mnlfischer對不起,你canno不要在任何地方發送密碼或散列。這是什麼意思,在這裏smtp? – Sliq

+0

@Panique我認爲他正在構建一個殭屍登錄系統:) –