PHP Username and Password Check Failing - php

When I register as a new user, and then try to login as that user, the username and/or password are not recognized. I've used this login system successfully in another application, but when I plugged it into a new application it started having this problem. I've checked everything and can't seem to find the issue. Any thoughts are greatly appreciated.
Here's the code:
<?php
function find_admin_by_username($username) {
global $connection;
$safe_username = mysqli_real_escape_string($connection, $username);
$query = "SELECT * ";
$query .= "FROM users ";
$query .= "WHERE username = '{$safe_username}' ";
$query .= "LIMIT 1";
$admin_set = mysqli_query($connection, $query);
confirm_query($admin_set);
if($admin = mysqli_fetch_assoc($admin_set)) {
return $admin;
} else {
return null;
}
}
function password_encrypt($password) {
$hash_format = "$2y$10$"; // Tells PHP to use Blowfish with a "cost" of 10
$salt_length = 22;
$salt = generate_salt($salt_length);
$format_and_salt = $hash_format . $salt;
$hash = crypt($password, $format_and_salt);
return $hash;
}
function generate_salt($length) {
// Not 100% unique, not 100% random, but good enough for a salt
// MD5 returns 32 characters
$unique_random_string = md5(uniqid(mt_rand(), true));
// Valid characters for a salt are [a-zA-Z0-9./]
$base64_string = base64_encode($unique_random_string);
// But not '+' which is valid in base64 encoding
$modified_base64_string = str_replace('+', '.', $base64_string);
// Truncate string to the correct length
$salt = substr($modified_base64_string, 0, $length);
return $salt;
}
function password_check($password, $existing_hash) {
// existing hash contains format and salt at start
$hash = crypt($password, $existing_hash);
if ($hash === $existing_hash) {
return true;
} else {
return false;
}
}
function attempt_login($username, $password) {
$admin = find_admin_by_username($username);
if ($admin) {
// found admin, now check password
if (password_check($password, $admin["password"])) {
// password matches
return $admin;
} else {
// password does not match
return false;
}
} else {
// admin not found
return false;
}
}
?>
<?php
if (isset($_POST['submit'])) {
// Process the form
// validations
$required_fields = array("username", "password");
validate_presences($required_fields);
if (empty($errors)) {
// Attempt Login
$username = $_POST["username"];
$password = $_POST["password"];
$found_admin = attempt_login($username, $password);
if ($found_admin) {
// Success
// Mark user as logged in
$_SESSION["admin_id"] = $found_admin["id"];
$_SESSION["username"] = $found_admin["username"];
redirect_to("MyAccount.php");
} else {
// Failure
$_SESSION["message"] = "Username/password not found.";
}
}
} else {
// This is probably a GET request
} // end: if (isset($_POST['submit']))
?>

Related

PHP MySQL PDO Login / Registration system over PBKDF2 Encryption won't log in

I am working with a specific encryption ( PBKDF2 ) for some reasons.
I am now building the website and I am having an issue with the Log In system.
The Registration page works perfectly has desired.
I don't have any output of errors when I try to log in and still the password does not match.
Here is my registration.php :
<?php
require '../global.php';
$pdo = New Database();
$account->IPisBanned($_SERVER['REMOTE_ADDR']);
$account->isConnected();
if(!empty($_POST['username']) AND !empty($_POST['email']) AND !empty($_POST['password']) AND !empty($_POST['password_confirmation'])) {
$bdd = $pdo->query('SELECT id FROM users WHERE username = ?', [$core->F_HTML($_POST['username'])]);
if($bdd->rowCount() == 0) {
if(preg_match('`^([a-zA-Z0-9-=?!#]{3,15})$`', $core->F_HTML($_POST['username']))) {
$bdd2 = $pdo->query('SELECT id FROM users WHERE email = ?', [$core->F_HTML($_POST['email'])]);
if($bdd2->rowCount() == 0) {
if(filter_var($core->F_HTML($_POST['email']), FILTER_VALIDATE_EMAIL)) {
if($_POST['password'] == $_POST['password_confirmation']) {
if(strlen($_POST['password']) >= 6 AND strlen($_POST['password_confirmation']) >= 6) {
$iterations = 10000;
$length = 40;
$secret = "at_least_16_byte";
$salt = $secret.$_POST['username'];
$hash = hash_pbkdf2("sha1", $_POST['password'], $salt, $iterations, $length);
$hash = strtoupper($hash);
$bdd3 = $pdo->query('INSERT INTO users (username, password, mail, account_created, ip_reg) VALUES (?, ?, ?, ?, ?)', [$core->F_HTML($_POST['username']), $core->F_HTML($hash), $core->F_HTML($_POST['email']), time(), $_SERVER['REMOTE_ADDR']]);
$_SESSION['id'] = $pdo->lastInsertId();
echo 'success';
} else {
echo 'Passwords does not match.';
}
} else {
echo 'Password too short.';
}
} else {
echo 'Invalid email address.';
}
} else {
echo 'This Email is already used by another account.';
}
} else {
echo 'Invalid username.';
}
} else {
echo 'Username already in use.';
}
} else {
echo 'Required fields are emtpy.';
}
?>
And here is my login.php :
<?php
require '../global.php';
$pdo = New Database();
$account->IPisBanned($_SERVER['REMOTE_ADDR']);
$account->isConnected();
if(!empty($_POST['username']) AND !empty($_POST['password'])) {
$bdd = $pdo->query('SELECT * FROM users WHERE username = ?', [$core->F_HTML($_POST['username'])]);
$iterations = 10000;
$length = 40;
$secret = "at_least_16_byte";
$salt = $secret.$_POST['username'];
$hash = hash_pbkdf2("sha1", $_POST['password'], $salt, $iterations, $length);
$hash = strtoupper($hash);
if($bdd->rowcount() == 1) {
$req = $bdd->fetch();
if(password_verify($hash, $req['password'])) {
$account->UserisBanned($core->F_HTML($_POST['username']));
$_SESSION['id'] = $req['id'];
$account->Update($_SESSION['id']);
echo 'success';
} else {
echo 'The password is incorrect.';
}
} else {
echo 'The username does not exist.';
}
} else {
echo 'The required fields are empty.';
}
?>
I am strongly confused, I spent hours trying to fix this but I really can't. Thank you for your time :)
It seems that password_verify expects the first param to be the user's plain text password.
Try this:
password_verify($_POST['password'], $req['password'])
NOTE: this means you probably need to drop the strtoupper as well.
https://www.php.net/manual/en/function.password-verify.php
Note that password_hash() returns the algorithm, cost and salt as part
of the returned hash. Therefore, all information that's needed to
verify the hash is included in it. This allows the verify function to
verify the hash without needing separate storage for the salt or
algorithm information.
/**
* (PHP 5 >= 5.5.0, PHP 5)<br/>
*
* Checks if the given hash matches the given options.
* #link https://secure.php.net/manual/en/function.password-verify.php
* #param string $password The user's password.
* #param string $hash A hash created by password_hash().
* #return boolean Returns TRUE if the password and hash match, or FALSE otherwise.
* #since 5.5.0
*/
function password_verify ($password, $hash) {}
If you dont want to do that, you could drop the password_verify and do:
`if ($hash === $req['password'])`
#!/usr/local/bin/php
<?php
//================================================================
//PBKDF2 generator for PBKDF2 hashed password log in.eg, mosquitto auth-plug
// I got this generator from somewhere online.. credit go to original writer..
// I research again and again to got loging in Mosquitto server.
// Use this generator to generate password earlier or use in register.php
function password_hash($password, $salt = '', $algo = 'sha256', $iterations = 901, $key_len = 24, $salt_len = 12)
{
//salt len is 12 , ajust your own
$salt = 'pN94c3+KCcNvIV1v'; //I added for my own, to use php login. salt is need to be contant all the time
if($salt=='') $salt = base64_encode(openssl_random_pseudo_bytes($salt_len));
$key = base64_encode(openssl_pbkdf2($password, $salt, $key_len, $iterations, $algo));
return sprintf("PBKDF2$%s$%d$%s$%s\n",
$algo,
$iterations,
$salt,
$key);
}
$password = trim($argv[1]);
if(function_exists('readline'))
{
while($password=='')
{
$password = trim(readline('Enter password: '));
}
}
else
{
$handle = fopen ("php://stdin","r");
while($password=='')
{
echo 'Enter password: ';
$password = trim(fgets($handle));
echo chr(10);
}
fclose($handle);
}
echo 'PBKDF2 password generator for Mosquitto auth plugin [https://github.com/jpmens/mosquitto-auth-plug]',chr(10);`enter code here`
echo 'Encoding password = ',$password,chr(10);
echo mqtt_hash($password),chr(10);
?>
//==========================================================================
// and verify with this pattern in login.php and register php
// I wrote php script to use above sample function
// php code
<?php
include 'get_hash.php';
$username = $_GET['username'];
$plain_password = $_GET['password'];
$password = trim(get_hash($plain_password)); //trim white space
$Sql_Query = "select * from tblusers where username = '$username'";
$result = mysqli_query($con,$Sql_Query);
if (mysqli_num_rows($result)>0)
{
$row = mysqli_fetch_assoc($result);
if ($password == $row['pw']){
$status = "ok";
}
else
{
$status = "failed";
}
}
?>
get_hash.php
<?php
// can use login.php and register.php
function get_hash($password, $salt = '', $algo = 'sha256', $iterations = 901, $key_len = 24, $salt_len = 12)
{
$salt = 'pN94c3+KCcNvIV1v';
if($salt=='') $salt = base64_encode(openssl_random_pseudo_bytes($salt_len));
$key = base64_encode(openssl_pbkdf2($password, $salt, $key_len, $iterations, $algo));
return sprintf("PBKDF2$%s$%d$%s$%s\n",
$algo,
$iterations,
$salt,
$key);
}
?>

User logs in and is redirected to a page specific to them

Hey im creating a site with users that need to log in. For some reason after the user logs in with a successful combination of email and password, they are redirected to a blank index.php instead of the user_page.php that I have created. I know there are other questions similar to this, I have looked through them but was unable to implement their corrections into my own code.
$errors = array();
$message = "";
$email = "";
$password = "";
if(isset($_POST["submit"])) { //THIS CHECKS LOG IN INFORMATION
//form was submitted
//$email = trim($_POST["email"]);
//$password = trim($_POST["password"]);
//header('Location: user_page.php?id=' . $_SESSION['user_id']);
//Validations
$required_fields = array("email", "password");
validate_presences($required_fields);
foreach ($required_fields as $field){
$value = trim($_POST[$field]);
if (!has_presence($value)) {
$errors[$field] = ucfirst($field) . " can't be blank"?><br/><?php ;
}
}
if (empty ($errors)) {
//try to login in
$email = trim($_POST["email"]); //set the variables for use in the function so they can be used as a value in the form, if its been submitted prev it echos back
$password = trim($_POST["password"]);
$found_email = attempt_login($email, $password); //function find user or return null or false
if ($found_email) {
// Success
// Mark user as logged in
$_SESSION["email_id"] = $found_email["id"]; //better than using a cookie which is visible in browser
$_SESSION["email"] = $found_email["email"]; //always know what the user name can use it browser or return the value back
redirect_to("user_page.php");
} else {
// Failure
$_SESSION["message"] = "Email/password not found.";//do not alert as to which field was incorrect
}
}
} else {
/*$email = "";
$password = "";
$message = "";*/
} //if isset end
I have a separate page with validations and functions that come from my learning source. if any other information is needed let me know. Thank You!
functions
<?php
function redirect_to($new_location)
{
header("Location: " . $new_location);
exit;
}
function mysql_prep($string)
{
global $connection;
$escaped_string = mysqli_real_escape_string($connection, $string);
return $escaped_string;
}
function password_encrypt($password)
{
$hash_format = "$2y$10$"; // Tells PHP to use Blowfish with a "cost" of 10
$salt_length = 22; // Blowfish salts should be 22-characters or more
$salt = generate_salt($salt_length);
$format_and_salt = $hash_format . $salt;
$hash = crypt($password, $format_and_salt);
return $hash;
}
function generate_salt($length)
{
// Not 100% unique, not 100% random, but good enough for a salt
// MD5 returns 32 characters
$unique_random_string = md5(uniqid(mt_rand(), true));
// Valid characters for a salt are [a-zA-Z0-9./]
$base64_string = base64_encode($unique_random_string);
// But not '+' which is valid in base64 encoding
$modified_base64_string = str_replace('+', '.', $base64_string);
// Truncate string to the correct length
$salt = substr($modified_base64_string, 0, $length);
return $salt;
}
function password_check($password, $existing_hash)
{
// existing hash contains format and salt at start
$hash = crypt($password, $existing_hash);
if ($hash === $existing_hash) {
return true;
} else {
return false;
}
}
function find_all_users()
{
global $connection;
$query = "SELECT * ";
$query .= "From users ";
$query .= "ORDER BY position ASC";
$result = mysql_query($connection, $query);
confirm_query($user_set);
return $user_set;
}
function find_user_by_email($email)
{
global $connection;
$safe_email = mysqli_real_escape_string($connection, $email);
$query = "SELECT * ";
$query .= "FROM users ";
$query .= "WHERE email = '{$safe_email}' ";
$query .= "LIMIT 1";
$email_set = mysqli_query($connection, $query);
confirm_query($email_set);
if ($email = mysqli_fetch_assoc($email_set)) {
return $email;
} else {
return null;
}
}
function find_email_by_id($email_id)
{
global $connection;
$safe_email_id = mysqli_real_escape_string($connection, $email_id);
$query = "SELECT * ";
$query .= "FROM email ";
$query .= "WHERE id = {$safe_email_id} ";
$query .= "LIMIT 1";
$email_set = mysqli_query($connection, $query);
confirm_query($email_set);
if ($email = mysqli_fetch_assoc($email_set)) {
return $email;
} else {
return null;
}
}
function attempt_login($email, $password)
{
$email = find_user_by_email($email);
if ($email) {
// found user, now check password
if (password_check($password, $email["hashed_password"])) {
// password matches
return $email;
} else {
// password does not match
return false;
}
} else {
// user not found
return false;
}
}
function logged_in()
{
return isset($_SESSION['email_id']);
}
// function confirm_logged_in()
// {
// if (!logged_in()) {
// redirect_to("index.php");
// }
// }
?>

How to login to an existing user account with an encrypted (blowfish) password

I followed a tutorial on youtube on how to encrypt users password using the encrypt blowfish function. I have implemented it properly into my registration script, with it successfully registering an account and sending the encrypted password to the database. My issue though, is retrieving that encrypted password when trying to log a user in. When I try and login to an existing user, it gets down to that last else statement saying it doesn't exist, meaning the hashed password isn't being recognized.
Code for encrypt password function:
public function encryptPass($password, $rounds = 11)
{
$salt = "";
// creates array of capital letters A-Z & lowercase as well as #'s 0-9
$saltChars = array_merge(range('A', 'Z'), range('a', 'z'), range(0,9));
for($i = 0; $i < 22; $i++)
{
// randomize the array
$salt .= $saltChars[array_rand($saltChars)];
}
return crypt($password, sprintf('$2y$%02d$', $rounds) . $salt);
}
Code used to register an account:
/// REGISTER ACCOUNT ///
if(isset($_POST['register']))
{
// clean up the fields
$username = mysql_real_escape_string(trim($_POST['username']));
$emailid = mysql_real_escape_string(trim($_POST['emailid']));
$password = mysql_real_escape_string(trim($_POST['password']));
$confirmPassword = mysql_real_escape_string(trim($_POST['confirm_password']));
if($password == $confirmPassword)
{
$iUe = $dbMan->ifUsernameExist($username);
$iEe = $dbMan->ifEmailExist($emailid);
// if username and email don't already exist, continue with registration
if(!$iUe && !$iEe)
{
// encrypt the users password
$hashedPassword = $dbMan->encryptPass($password);
echo "$password <br> \n";
// register the account
$register = $dbMan->UserRegister($username, $emailid, $hashedPassword);
// if registration was succesful
if($register)
{
echo "<script>alert('Registration Successful')</script>";
}
else
{
echo "<script>alert('Registration Not Successful')</script>";
}
}
else
{
echo "<script>alert(' That email or username already exists! ')</script>";
}
}
else
{
echo "<script>alert(' Passwords do not match! ')</script>";
}
}
Code used for the login:
/// LOGIN ACCOUNT ///
if(isset($_POST['login']))
{
// 'convert' post variables to session variables
$_SESSION['username'] = $_POST['username'];
$_SESSION['password'] = $_POST['password'];
// clean em up, get rid of any white spaces or sql injection special chars
$username = mysql_real_escape_string(trim($_SESSION['username']));
$password = mysql_real_escape_string($dbMan->encryptPass(trim($_SESSION['password'])));
echo "$password<br>\n";
$user = $dbMan->Login($username, $password);
// if theres an acccount with that username/pw in the db
if ($user)
{
// login successful
header("location:index.php");
}
else
{
// Registration Failed
echo "<script>alert(' The email or password do not match! ')</script>";
}
}
Code for dbManager:
<?php
require_once 'dbConnect.php';
//session_start();
class dbManager
{
function __construct()
{
// connecting to database
$db = new dbConnect();
}
// destructor
function __destruct()
{
}
public function UserRegister($username, $emailid, $password)
{
$query = mysql_query("INSERT INTO users(username, emailid, password) values('".$username."','".$emailid."','".$password."')") or die(mysql_error());
return $query;
}
public function Login($username, $password)
{
$query = mysql_query("SELECT * FROM users WHERE username = '".$username."' AND password = '".$password."'");
$user_data = mysql_fetch_array($query);
//print_r($user_data);
$num_rows = mysql_num_rows($query);
if ($num_rows == 1)
{
$_SESSION['login'] = true;
$_SESSION['uid'] = $user_data['id'];
$_SESSION['username'] = $user_data['username'];
$_SESSION['emailid'] = $user_data['emailid'];
return TRUE;
}
else
{
return FALSE;
}
}
// check if username exists in db
public function ifUsernameExist($username)
{
$qr = mysql_query("SELECT * FROM users WHERE username = '".$username."'");
echo $row = mysql_num_rows($qr);
if($row > 0)
{
return TRUE;
}
else
{
return FALSE;
}
}
// check if email exists in db
public function ifEmailExist($emailid)
{
$qr = mysql_query("SELECT * FROM users WHERE emailid = '".$emailid."'");
echo $row = mysql_num_rows($qr);
if($row > 0)
{
return TRUE;
}
else
{
return FALSE;
}
}
// encrypt password
public function encryptPass($password, $rounds = 11)
{
$salt = "";
// creates array of capital letters A-Z & lowercase as well as #'s 0-9
$saltChars = array_merge(range('A', 'Z'), range('a', 'z'), range(0,9));
for($i = 0; $i < 22; $i++)
{
// randomize the array
$salt .= $saltChars[array_rand($saltChars)];
}
return crypt($password, sprintf('$2y$%02d$', $rounds) . $salt);
}
}
?>
Note: both the login and register 'methods' are in the same php file including the form markup. The encrypted function is located in a different file called dbManager.
Hopefully I provide enough information for someone to point me in the right direction. Any help is appreciated!
Thanks, Dev.
You need to pass your cleartext password to encrypt to compare it within the database.
change
$password = trim(mysql_real_escape_string($_SESSION['password']));
to
$password = $dbMan->encryptPass(trim(mysql_real_escape_string($_SESSION['password'])));
In your login action.
Ideally you would run the $dbMan->encryptPass before doing mysql_real_escape_string both on INSERTand SELECT.
$password = mysql_real_escape_string($dbMan->encryptPass(trim($_SESSION['password'])));
The salts have to be the same for encrypt and decrypt, seeing as you are using array_rand the salts are different on each pass. You have to store the salt someplace else. If you remove the salt or set it to a constant it will work now.

Parse error: syntax error, unexpected '?'

I have been trying to follow a guide for making a PHP server app and I am getting a few syntax errors.
Error message:
Parse error: syntax error, unexpected '?' in
D:\inetpub\wwwroot\cmpswoo1\CMPPROJ_Web\ServerApp\api2\db_functions2.php on line 134
So I know were the error is, I just don't know how to fix it
<?php
class db_functions2 {
private $db;
//put your code here
// constructor
function __construct() {
require_once 'db_connect2.php';
// connecting to database
$this->db = new db_connect2();
$this->db->connect();
}
// destructor
function __destruct() {
}
/**
* Random string which is sent by mail to reset password
*/
public function random_string()
{
$character_set_array = array();
$character_set_array[] = array('count' => 7, 'characters' => 'abcdefghijklmnopqrstuvwxyz');
$character_set_array[] = array('count' => 1, 'characters' => '0123456789');
$temp_array = array();
foreach ($character_set_array as $character_set) {
for ($i = 0; $i < $character_set['count']; $i++) {
$temp_array[] = $character_set['characters'][rand(0, strlen($character_set['characters']) - 1)];
}
}
shuffle($temp_array);
return implode('', $temp_array);
}
public function forgotPassword($forgotpassword, $newpassword, $salt){
$result = mysql_query("UPDATE `Users` SET `encryptedPassword` = '$newpassword',`salt` = '$salt'
WHERE `email` = '$forgotpassword'");
if ($result) {
return true;
}
else
{
return false;
}
}
/**
* Adding new user to mysql database
* returns user details
*/
public function storeUser($FirstName, $LastName, $DOB, $email, $Username, $Password) {
$uuid = uniqid('', true);
$hash = $this->hashSSHA($Password);
$encrypted_password = $hash["encrypted"]; // encrypted password
$salt = $hash["salt"]; // salt
$result = mysql_query("INSERT INTO Users(unique_id, FirstName, LastName, email, DOB, Username, encryptedPassword, salt, created_at) VALUES('$uuid', '$FirstName', '$LastName', '$email', '$DOB', '$Username', '$encryptedPassword', '$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 = $id");
// return user details
return mysql_fetch_array($result);
} else {
return false;
}
}
/**
* Verifies user by username and password
*/
public function getUserByUsernameAndPassword($Username, $Password) {
$result = mysql_query("SELECT * FROM Users WHERE usernameE = '$Username'") 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['encryptedPassword'];
$hash = $this->checkhashSSHA($salt, $Password);
// check for password equality
if ($encryptedPassword == $hash) {
// user authentication details are correct
return $result;
}
} else {
// user not found
return false;
}
}
/**
* Checks whether the username is valid or fake
*/
public function validUsername($Username)
{
$isValid = true;
$atIndex = strrpos($Username, "#");
if (is_bool($atIndex) && !$atIndex)
{
$isValid = false;
}
else
{
$domain = substr($Username, $atIndex+1);
$local = substr($Username, 0, $atIndex);
$localLen = strlen($local);
$domainLen = strlen($domain);
if ($localLen < 1 || $localLen > 64)
{
// local part length exceeded
$isValid = false;
}
else if ($domainLen < 1 || $domainLen > 255)
{
// domain part length exceeded
$isValid = false;
}
else if ($local[0] == '.' || $local[$localLen-1] == '.')
{
// local part starts or ends with '.'
$isValid = false;
}
else if (preg_match('/\.\./', $local))
{
// local part has two consecutive dots
$isValid = false;
}
else if (!preg_match('/^[A-Za-z0-9\-\.]+$/', $domain))
{
// character not valid in domain part
$isValid = false;
}
else if (preg_match('/\.\./', $domain))
{
// domain part has two consecutive dots
$isValid = false;
}
else if
(!preg_match('/^(\\.|[A-Za-z0-9!#%&`_=\/$'*+?^{}|~.-])+$/',str_replace("\\","",$local)))
{
// character not valid in local part unless
// local part is quoted
if (!preg_match('/^"(\\"|[^"])+"$/',
str_replace("\\","",$local)))
{
$isValid = false;
}
}
if ($isValid && !(checkdnsrr($domain,"MX") ||checkdnsrr($domain,"A")))
{
// domain not found in DNS
$isValid = false;
}
}
return $isValid;
}
/**
* Check user is existed or not
*/
public function isUserExisted($Username) {
$result = mysql_query("SELECT Username from Users WHERE Username = '$Username'");
$no_of_rows = mysql_num_rows($result);
if ($no_of_rows > 0) {
// user existed
return true;
} else {
// user not existed
return false;
}
}
/**
* Encrypting 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
* returns hash string
*/
public function checkhashSSHA($salt, $Password) {
$hash = base64_encode(sha1($Password . $salt, true) . $salt);
return $hash;
}
}
?>
Here single quote is causing problem:
So, change
(!preg_match('/^(\\.|[A-Za-z0-9!#%&`_=\/$'*+?^{}|~.-])+$/',str_replace("\\","",$local)))
To:
(!preg_match('/^(\\.|[A-Za-z0-9!#%&`_=\/$\'*+?^{}|~.-])+$/',str_replace("\\","",$local)))
The regular expression string is opened with ', but also contains a '. Escape it with \. The error should be gone.
(!preg_match('/^(\\.|[A-Za-z0-9!#%&`_=\/$'*+?^{}|~.-])+$/',str_replace("\\","",$local)))
Should be
(!preg_match('/^(\\.|[A-Za-z0-9!#%&`_=\/$\'*+?^{}|~.-])+$/',str_replace("\\","",$local)))

Can login even if only the password is partially correct?

I acciedentley stumbled upon a problem with my login form. I seem to be able to login in when the password is partially correct.
If i create the following user:
Username: hehehehehe
Password: hehehehehe
I can login with passwords like "hehehehe", "hehehehehe11111" etc. If i write it completely wrong, it doesn't work.
Login.php
if (empty($_POST) === false) {
$username = trim($_POST['username']);
$password = trim($_POST['password']);
if (empty($username) === true || empty($password) === true) {
$errors[] = 'Sorry, but we need your username and password.';
} else if ($users->user_exists($username) === false) {
$errors[] = 'Sorry that username doesn\'t exists.';
// } else if ($users->email_confirmed($username) === false) {
// $errors[] = 'Sorry, but you need to activate your account.
// Please check your email.';
} else {
if (strlen($password) > 18) {
$errors[] = 'The password should be less than 18 characters, without spacing.';
}
$login = $users->login($username, $password);
if ($login === false) {
$errors[] = 'Sorry, that username/password is invalid';
}else {
$_SESSION['id'] = $login;
header('Location: home.php');
exit();
}
}
}
User.class.php
public function login($username, $password) {
global $bcrypt;
$query = $this->db->prepare("SELECT `password`, `user_id` FROM `users` WHERE `username` = ?");
$query->bindValue(1, $username);
try{
$query->execute();
$data = $query->fetch();
$stored_password = $data['password'];
$id = $data['user_id'];
if($bcrypt->verify($password, $stored_password) === true){
return $id;
}else{
return false;
}
}catch(PDOException $e){
die($e->getMessage());
}
}
Bcrypt.class.php
class Bcrypt {
private $rounds;
public function __construct($rounds = 12) {
if(CRYPT_BLOWFISH != 1) {
throw new Exception("Bcrypt is not supported on this server, please see the following to learn more: http://php.net/crypt");
}
$this->rounds = $rounds;
}
private function genSalt() {
$string = str_shuffle(mt_rand());
$salt = uniqid($string ,true);
return $salt;
}
public function genHash($password) {
$hash = crypt($password, '$2y$' . $this->rounds . '$' . $this->genSalt());
return $hash;
}
public function verify($password, $existingHash) {
$hash = crypt($password, $existingHash);
if($hash === $existingHash) {
return true;
} else {
return false;
}
}
}
Any ideas?
If you guys thinks it could do with the registration process, please let me know and i'll upload the register code aswell. What i can't figure out is that why it works even if just parts of the password is correct, I've never experienced that before.
It seems crypt is using DES for hashing rather than blowfish:
http://php.net/manual/en/function.crypt.php
The standard DES-based crypt() returns the salt as the first two characters of the output. It also only uses the first eight characters of str, so longer strings that start with the same eight characters will generate the same result (when the same salt is used).
Try to login with just the first 8 characters using your code.
Also have a look at the saved hashes stored in your database to see if they're using blowfish or DES. If using blowfish they should have the $2y$ signature you used.

Categories