Jump to content

[SOLVED] Hash password


mbrown

Recommended Posts

so i would have them register.

 

create the hash and it inserted it into the database

 

then next when they try to log in with the password they entered do the same hashing technique before and say if the password entered is == to hashed password in db then let them in?

 

if i provide some code would you guys be able to help me out?

Link to comment
Share on other sites

my next question is going to be really stupid

 

what is the line that is to pull the username and password from the db. i mean it will look for the entered username in the db and make sure the pw is the same one for that account.

 

Thats done in your query. eg;

 

SELECT uname FROM users WHERE uname = '$uname' && upass = '$upass';

Link to comment
Share on other sites

so like

$password = $_POST['$password'];
$username = $_POST['$username'];
$dbusername = "SELECT uname FROM users WHERE uname = '$username ' && upass = '$password '";
$dbpassword= "SELECT upass FROM users WHERE uname = '$username ' && upass = '$password '";

if ($username != $dbusername || $password != $dbpassword )
{
$error .= "Invalid Credentials";
}

 

Is this correct then?

 

Link to comment
Share on other sites

There's a lot to think about when authenticating a user. I'm certainly no expert, but I've been working for a long while (in my spare time) on a login system. Searching the internet for topics such as "session hijacking" and "session fixation", as well as "sql injection", "XSS attacks", etc. will give you a good preview of what you will be planning for when making your login script. I'm going to post some code below for you to check out. This is only part of the login script I've been working on, but it might help steer you in a direction where you understand more about what you are doing:

 

<?php
/*
This script is used to check if a person is a user or admin.
Cookies, must be enabled on the client's browser for this 
script to work. Another option would be to have the 
session ID appended to the URL by setting session.use_trans_sid
to true in the server's php.ini file.

Author:	Robert Brian Gottier
Date:	January 15, 2009

Example usage for a user page:

	if (!isset($user_is_logged_in) || $user_is_logged_in == 'false') { 
		//show login form, or redirect to the login form
	}else{
		// display user's content
		// the specific user is determined by the $clean_user_id variable
	}

Example usage for an admin page:

	if (!isset($admin_is_logged_in) || $admin_is_logged_in == 'false') {
		//show login form, or redirect to the login form
	}else{
		// display admin's content
	}

SQL to get started:

	CREATE TABLE `admins` (
	  `admin_id` tinyint(3) NOT NULL auto_increment,
	  `username` varchar(12) NOT NULL,
	  `password` varchar(40) NOT NULL,
	  `timestamp` int(10) NOT NULL,
	  `login_hold` int(10) NOT NULL default '0',
	  PRIMARY KEY  (`admin_id`),
	  UNIQUE KEY `username` (`username`)
	) ENGINE=InnoDB;

	CREATE TABLE `admin_login_attempts` (
	  `admin_id` tinyint(3) NOT NULL,
	  `attempt_count` tinyint(2) NOT NULL default '0',
	  `last_attempt` int(10) NOT NULL
	) ENGINE=InnoDB;

	CREATE TABLE `ip_login_attempts` (
	  `IPaddr` varchar(15) NOT NULL,
	  `attempt_count` tinyint(2) NOT NULL,
	  `login_hold` int(10) default '0',
	  `last_attempt` int(10) NOT NULL
	) ENGINE=InnoDB;

	CREATE TABLE `users` (
	  `user_id` smallint(5) NOT NULL auto_increment,
	  `username` varchar(12) NOT NULL,
	  `password` varchar(40) NOT NULL,
	  `timestamp` int(10) NOT NULL,
	  `login_hold` int(10) NOT NULL default '0',
	  PRIMARY KEY  (`user_id`),
	  UNIQUE KEY `username` (`username`)
	) ENGINE=InnoDB;

	CREATE TABLE `user_login_attempts` (
	  `user_id` smallint(5) NOT NULL,
	  `attempt_count` tinyint(2) NOT NULL default '0',
	  `last_attempt` int(10) NOT NULL
	) ENGINE=InnoDB;

Users and admins will still need to be able to log out.
Logging out usually requires that the session is unset,
and that the user or admin is redirected to somewhere.
*/
// initialize some variables
$user_is_logged_in = 'false';
$login_error = 0;
$admin_is_logged_in = 'false';
$admin_login_error = 0;

// check if this is a login form submission
if(isset($post_submit_login) && $post_submit_login == 'submit'){

// If the form post did not come from the same domain on the development or production server, according to the HTTP_REFERER value, then the form post is an attack because of the way I have implemented the login form.
if (isset($_SERVER['HTTP_REFERER']) && !stristr($_SERVER['HTTP_REFERER'], DOMAIN ) && !stristr($_SERVER['HTTP_REFERER'], SHARED_SSL_DOMAIN ) && !stristr($_SERVER['HTTP_REFERER'], LOCAL_DOMAIN )){
	die('die!');
}

// If the POST vars did not pass filter_input()
if ($post_login_username == FALSE || $post_login_username == NULL || $post_login_password == FALSE || $post_login_password == NULL){
	$login_error = 1;
	$user_is_logged_in = 'false';
	$admin_login_error = 1;
	$admin_is_logged_in = 'false';
}

// A username or password can not be more than MAX_USERNAME_LENGTH or MAX_PASSWORD_LENGTH characters, and a password cannot be less than MIN_PASSWORD_LENGTH chracters. If either posted values are not the appropriate character length, login fails
if( strlen( $post_login_username ) > MAX_USERNAME_LENGTH || strlen( $post_login_password ) > MAX_PASSWORD_LENGTH || strlen( $post_login_password ) < MIN_PASSWORD_LENGTH ){
	$login_error = 1;
	$user_is_logged_in = 'false';
	$admin_login_error = 1;
	$admin_is_logged_in = 'false';
}

// Check if the remote IP address is on hold
// This might hinder a brute force attack if the attacker isn't spoofing the IP address
$ip_on_hold = 0;
if( isset($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] != '' && $_SERVER['REMOTE_ADDR'] != NULL ){
	$clean_remote_ip = clean_for_query($_SERVER['REMOTE_ADDR']);
	$k = mysqli_query($db , "SELECT login_hold FROM `ip_login_attempts` WHERE IPaddr = '$clean_remote_ip' LIMIT 1");
	$l = mysqli_num_rows($k);
	if($l == 1){
		$row = mysqli_fetch_assoc($k);
		if ($row['login_hold'] > time() ){
			$user_is_logged_in = 'false';
			$admin_is_logged_in = 'false';
			$login_error = 1;
			$admin_login_error = 1;
			$ip_on_hold = 1;
		}
	}
	mysqli_free_result($k);
}

//  check if the user is on hold
$user_on_hold = 0;
$clean_login_username = clean_for_query($post_login_username);
$m = mysqli_query($db , "SELECT login_hold FROM `users` WHERE username = '$clean_login_username' LIMIT 1");
$n = mysqli_num_rows($m);
if($n == 1){
	$row = mysqli_fetch_assoc($m);
	if ($row['login_hold'] > time() ){
		$user_is_logged_in = 'false';
		$login_error = 1;
		$user_on_hold = 1;
	}
}
mysqli_free_result($m);

// check if the admin is on hold
$admin_on_hold = 0;
$clean_login_username = clean_for_query($post_login_username);
$m = mysqli_query($db , "SELECT login_hold FROM `admins` WHERE username = '$clean_login_username' LIMIT 1");
$n = mysqli_num_rows($m);
if($n == 1){
	$row = mysqli_fetch_assoc($m);
	if ($row['login_hold'] > time() ){
		$admin_is_logged_in = 'false';
		$admin_login_error = 1;
		$admin_on_hold = 1;
	}
}
mysqli_free_result($m);

// If the login attempt seems normal so far, and the login attempt has not produced an error thus far, do potential clean-up of the database.
// This could be put into a cron job, but in case a person has no access to cron, then it ought to be performed here.
if( $user_on_hold == 0 && $admin_on_hold == 0 && $ip_on_hold == 0 && $login_error == 0 && $admin_login_error == 0 ){
	$old_hold = time() - ( LOGIN_RESTRICTION_MINS * 60);
	mysqli_query($db , "DELETE FROM `user_login_attempts` WHERE last_attempt < '$old_hold';
						DELETE FROM `admin_login_attempts` WHERE last_attempt < '$old_hold';
						DELETE FROM `ip_login_attempts` WHERE last_attempt < '$old_hold'"  );
}

// if there was no error with login form submission validation, check if the user's username and password match a database row
if($login_error != 1 && $user_on_hold != 1 && $ip_on_hold != 1){
	$clean_login_username = clean_for_query($post_login_username);
	$clean_login_password = clean_for_query($post_login_password);
	$super_password = sha1(PASSWORD_SALT . $clean_login_password);
	$a = mysqli_query($db , "SELECT * FROM `users` WHERE username = '$clean_login_username' AND password = '$super_password' LIMIT 1");
	$b = mysqli_num_rows($a);
	if($b == 1){ // if they match, then add some session keys, and $user_is_logged_in = 'true'
		$row = mysqli_fetch_assoc($a);
		$fingerprint = $row['timestamp'];
		session_regenerate_id();
		$_SESSION['user_id'] = $row['user_id'];
		$_SESSION['user_token'] = sha1($fingerprint . session_id() . $_SERVER['HTTP_USER_AGENT']);
		$user_is_logged_in = 'true';
		mysqli_query($db , "UPDATE `users` SET login_hold = 0 WHERE user_id = '{$row['user_id']}' LIMIT 1");
		mysqli_query($db , "DELETE FROM `user_login_attempts` WHERE user_id = '{$row['user_id']}' LIMIT 1");
		if( isset($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] != '' && $_SERVER['REMOTE_ADDR'] != NULL ){ // clean up the ip_login_attempts log
			$clean_remote_ip = clean_for_query($_SERVER['REMOTE_ADDR']);
			mysqli_query($db , "DELETE FROM `ip_login_attempts` WHERE IPaddr = '$clean_remote_ip' LIMIT 1");
		}
	}else{ // if they don't match, then the form submission matched no user
		$login_error = 1;
		$user_is_logged_in = 'false';
	}
	mysqli_free_result($a);
}

// if there was no error with login form submission validation, check if the admin's username and password match a database row
if($admin_login_error != 1 && $admin_on_hold != 1 && $ip_on_hold != 1){ 
	$clean_login_username = clean_for_query($post_login_username);
	$clean_login_password = clean_for_query($post_login_password);
	$super_password = sha1(PASSWORD_SALT . $clean_login_password);
	$a = mysqli_query($db , "SELECT * FROM `admins` WHERE username = '$clean_login_username' AND password = '$super_password' LIMIT 1");
	$b = mysqli_num_rows($a);
	if($b == 1){ // if they match, then add some session keys, and $admin_is_logged_in = 'true'
		$row = mysqli_fetch_assoc($a);
		$fingerprint = $row['timestamp'];
		session_regenerate_id();
		$_SESSION['admin_id'] = $row['admin_id'];
		$_SESSION['admin_token'] = sha1($fingerprint . session_id() . $_SERVER['HTTP_USER_AGENT']);
		$admin_is_logged_in = 'true';
		mysqli_query($db , "UPDATE `admins` SET login_hold = 0 WHERE admin_id = '{$row['admin_id']}' LIMIT 1");
		mysqli_query($db , "DELETE FROM `admin_login_attempts` WHERE admin_id = '{$row['admin_id']}' LIMIT 1");
		if( isset($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] != '' && $_SERVER['REMOTE_ADDR'] != NULL ){ // clean up the ip_login_attempts log
			$clean_remote_ip = clean_for_query($_SERVER['REMOTE_ADDR']);
			mysqli_query($db , "DELETE FROM `ip_login_attempts` WHERE IPaddr = '$clean_remote_ip' LIMIT 1");
		}
	}else{ // if they don't match, then the form submission matched no admin
		$admin_login_error = 1;
		$admin_is_logged_in = 'false';
	}
	mysqli_free_result($a);
}

$try_ip = 0;
// If a login attempt was made with an actual user's username, but the password was wrong, log the attempt
if( $login_error == 1 ){ 
	$clean_login_username = clean_for_query($post_login_username);
	$e = mysqli_query($db , "SELECT user_id FROM users WHERE username ='$clean_login_username' LIMIT 1");
	$f = mysqli_num_rows($e);
	if ( $f == 1 ){ // If the post contains a real username
		$row = mysqli_fetch_assoc($e);
		$failed_user_id = $row['user_id'];
		mysqli_free_result($e);
		$i = mysqli_query($db , "SELECT attempt_count FROM user_login_attempts WHERE user_id ='$failed_user_id' LIMIT 1");
		$j = mysqli_num_rows($i);
		if ( $j == 1 ){ // If the user already has a failed login attempt
			$row = mysqli_fetch_assoc($i);
			$previous_attempts = $row['attempt_count'];
			$current_attempts = $previous_attempts + 1;
			$hold_time = time() + ( LOGIN_RESTRICTION_MINS * 60);
			if ($current_attempts >= LOGIN_ATTEMPT_LIMIT) { // set or reset the login hold if the user has LOGIN_ATTEMPT_LIMIT failed login attempts or greater
				mysqli_query($db, "UPDATE `users` SET login_hold = '$hold_time' WHERE user_id = '$failed_user_id'");
			}
			mysqli_query($db, "UPDATE `user_login_attempts` SET attempt_count = '$current_attempts' , last_attempt = " . time() . " WHERE user_id = '$failed_user_id'");
		}else{ // Else create a database row to start loggin failed login attempts
			mysqli_query($db, "INSERT INTO `user_login_attempts` (user_id,attempt_count,last_attempt) VALUES ('$failed_user_id',1," . time() . ")");
		}
		mysqli_free_result($i);
	}else{
		$try_ip = 1;
	}
}

// If a login attempt was made with an actual admin's username, but the password was wrong, log the attempt
if( $admin_login_error == 1 ){ 
	$clean_login_username = clean_for_query($post_login_username);
	$e = mysqli_query($db , "SELECT admin_id FROM admins WHERE username ='$clean_login_username' LIMIT 1");
	$f = mysqli_num_rows($e);
	if ( $f == 1 ){ // If the post contains a real admin's username
		$row = mysqli_fetch_assoc($e);
		$failed_admin_id = $row['admin_id'];
		mysqli_free_result($e);
		$i = mysqli_query($db , "SELECT attempt_count FROM admin_login_attempts WHERE admin_id ='$failed_admin_id' LIMIT 1");
		$j = mysqli_num_rows($i);
		if ( $j == 1 ){ // If the admin already has a failed login attempt
			$row = mysqli_fetch_assoc($i);
			$previous_attempts = $row['attempt_count'];
			$current_attempts = $previous_attempts + 1;
			$hold_time = time() + ( LOGIN_RESTRICTION_MINS * 60);
			if ($current_attempts >= LOGIN_ATTEMPT_LIMIT) { // set or reset the login hold if the admin has LOGIN_ATTEMPT_LIMIT failed login attempts or greater
				mysqli_query($db, "UPDATE `admins` SET login_hold = '$hold_time' WHERE admin_id = '$failed_admin_id'");
			}
			mysqli_query($db, "UPDATE `admin_login_attempts` SET attempt_count = '$current_attempts' , last_attempt = " . time() . " WHERE admin_id = '$failed_admin_id'");
		}else{ // Else create a database row to start loggin failed login attempts
			mysqli_query($db, "INSERT INTO `admin_login_attempts` (admin_id,attempt_count,last_attempt) VALUES ('$failed_admin_id',1," . time() . ")");
		}
		mysqli_free_result($i);
	}else{
		$try_ip += $try_ip;
	}
}

// If a login attempt was made with no match for user's username or admin's username, log the attempt by IP address (if possible)
if($try_ip == 2){ 
	if(isset($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] != '' && $_SERVER['REMOTE_ADDR'] != NULL){
		$clean_remote_ip = clean_for_query($_SERVER['REMOTE_ADDR']);
		$g = mysqli_query($db , "SELECT attempt_count FROM ip_login_attempts WHERE IPaddr = '$clean_remote_ip'");
		$h = mysqli_num_rows($g);
		if ( $h == 1 ){
			$row = mysqli_fetch_assoc($g);
			$previous_attempts = $row['attempt_count'];
			$current_attempts = $previous_attempts + 1;
			$hold_time = time() + ( LOGIN_RESTRICTION_MINS * 60);
			if ($current_attempts >= LOGIN_ATTEMPT_LIMIT) {
				mysqli_query($db, "UPDATE `ip_login_attempts` SET attempt_count = '$current_attempts', last_attempt = '" . time() . "', login_hold = '$hold_time' WHERE IPaddr = '$clean_remote_ip'");
			}else{
				mysqli_query($db, "UPDATE `ip_login_attempts` SET attempt_count = '$current_attempts', last_attempt = '" . time() . "' WHERE IPaddr = '$clean_remote_ip'");
			}
		}else{
			mysqli_query($db, "INSERT INTO `ip_login_attempts` (IPaddr,attempt_count,last_attempt) VALUES ( '$clean_remote_ip' , 1 , " . time() . ")");
		}
		mysqli_free_result($g);
	}
}

// If max logins are preventing a user / admin / attacker from logging in, show this message
if ( $user_on_hold == 1 || $admin_on_hold == 1 || $ip_on_hold == 1 ){
	echo "You have exceeded a normal number of login attempts, and must now wait " . LOGIN_RESTRICTION_MINS . " minutes before trying again. Please come back later.";
}
}

// if the user or admin is not logging in through the form, we need to check who they are

// the session variables are used to see if the person is a user
if(isset($_SESSION['user_id']) && isset($_SESSION['user_token'])){
$clean_user_id = clean_for_query($_SESSION['user_id']);
$c = mysqli_query($db , "SELECT * FROM `users` WHERE user_id = '$clean_user_id' LIMIT 1");
$d = mysqli_num_rows($c);
if($d == 1){ // if there was a match for the user's ID, we proceed to check the token
	$row = mysqli_fetch_assoc($c);
	$fingerprint = $row['timestamp'];
	if($_SESSION['user_token'] = sha1($fingerprint . session_id() . $_SERVER['HTTP_USER_AGENT'])){ // user's timestamp, session ID, and user agent must stay the same
		session_regenerate_id();
		$user_is_logged_in = 'true';
	}else{ // if user's timestamp, session ID, and user agent are not the same, they will have to log in again
		$login_error = 1;
		$user_is_logged_in = 'false';
	}
}
mysqli_free_result($c);
}

// the session variables are used to see if the person is an admin
if(isset($_SESSION['admin_id']) && isset($_SESSION['admin_token'])){
$clean_admin_id = clean_for_query($_SESSION['admin_id']);
$c = mysqli_query($db , "SELECT * FROM `admins` WHERE admin_id = '$clean_admin_id' LIMIT 1");
$d = mysqli_num_rows($c);
if($d == 1){ // if there was a match for the admin's ID, we proceed to check the token
	$row = mysqli_fetch_assoc($c);
	$fingerprint = $row['timestamp'];
	if($_SESSION['admin_token'] = sha1($fingerprint . session_id() . $_SERVER['HTTP_USER_AGENT'])){ // admin's timestamp, session ID, and user agent must stay the same
		session_regenerate_id();
		$admin_is_logged_in = 'true';
	}else{ // if admin's timestamp, session ID, and user agent are not the same, they will have to log in again
		$admin_login_error = 1;
		$admin_is_logged_in = 'false';
	}
}
mysqli_free_result($c);
}
?>

Link to comment
Share on other sites

my system is just for admins. there are no user log ins since they will not have access to the website. it is only for people who have accounts who will be the admins so i will not need to see if they have user or admin privleges. I just need a very basic login and auth script that I have to create.

 

is what i had earlier a "basic" auth script?

Link to comment
Share on other sites

Is this correct then?

 

Well, you were asking about hashed passwords and verifying those... and your code does neither as people suggested.  For example, if you're storing your passwords as SHA-1 in the database, you could do this:

 

$password = $_POST['$password'];
$username = $_POST['$username'];
$dbusername = "SELECT uname FROM users WHERE uname = '$username' && upass = '$password'";
$dbpassword= "SELECT upass FROM users WHERE uname = SHA1('$username') && upass = SHA1('$password')";

 

Technically, you could do that in one query, but I could see how it would be easier to start learning with separate variables.  Oh, and here's a good reference on MySQL Encryption functions:  http://dev.mysql.com/doc/refman/5.1/en/encryption-functions.html

 

Finally, for comparing the user and pass, you got some good advice on using string comparisons... so, put 'em to use!  Examples from the advice given earlier in the thread:

 

if ( $username !== $dbusername || !strcmp(sha1($password),$dbpassword) )
{
$error .= "Invalid Credentials";
}

 

Just take your time and read through the replies you get a couple times.  If they don't make sense right off, just keep at it and give it time... but at least try to research the functions and methods that people are recommending to you so that you can understand how they work and why they're good.

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.