...

View Full Version : problem with sha1



Bob42
01-17-2008, 05:18 AM
Right now I'm creating a login/register user system that encrypts passwords with sha1(). The password does get stored in a hash in the database. The problem that I'm having is that when I try to login using my password, I get my "Invalid login!" message.

My registration form (adds a user to the database):



$user = mysql_real_escape_string($_POST[username]);
$pass = sha1($_POST[password]);
$sql = "INSERT INTO admins (username, password, status)
VALUES ('$user', '$pass', '$status')";
if (!mysql_query($sql,$con))
{
die('Error: ' . mysql_error());
}
echo "User added successfully to the database!";


My login script:



$username = mysql_real_escape_string($_POST['username']);
$password = sha1($_POST['password']);
$sql = "SELECT * FROM admins WHERE username='$username' and password='$password'";
$result = mysql_query($sql);
$rs = mysql_fetch_assoc($result);
$count = mysql_num_rows($result);
if($count == 1){
$_SESSION['username'] = $username;
$_SESSION['password'] = $password;
$_SESSION['status'] = $rs['status'];
$_SESSION['db_logged_in'] = true;
header("location:panel.php");
}
else {
echo "Invalid login!";
}


What am I doing wrong here?

Jon W
01-17-2008, 05:50 AM
Try to encrypt your passwords with md5(). I've never heard of sha1() before, I'll have to look that one up. But when I do it with my passwords on my site I will use md5().

Hopes this help!

Jon W

Edit: Hrmm.. also I would use PHP to check and see if the person has filled in the fields or not before you connect to MYSQL. You could wake up the next day and there would be 500 new accounts in your Database that are blank. The thing I would do is this:




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

if($_POST['username'] !='' && $_POST['password'] !='')
{
$con = mysql_connect('hostname','username','password');
if(!$con)
{
die('Database error: ' . mysql_error());
}
mysql_select_db('db', $con);

$username = mysql_real_escape_sting($_POST['username']);
$password = mysql_real_escape_string(md5($_POST['password']));

$query = mysql_query("INSERT INTO table (username, password) VALUES('$username', '$password')") or die('Database error: ' . mysql_error());

}
}
else
{
$error = 'Please fill in a Username and Password before hitting Submit';
}

}

?>

StupidRalph
01-17-2008, 07:10 AM
Try to encrypt your passwords with md5(). I've never heard of sha1() before
md5 is a 32 character hash
sha1 is a 40 character hash

@Bob
Add some error checking to your login script and make sure the query is running. You could also, var_dump($rs) and echo out $count.

Fou-Lu
01-17-2008, 03:44 PM
md5 is a 32 character hash
sha1 is a 40 character hash

@Bob
Add some error checking to your login script and make sure the query is running. You could also, var_dump($rs) and echo out $count.

I'm with ralph on this one, ensure that the query is fetching the correct result set. Trying to remember off hand (ralph you may know off hand), but some of the algorithms require a salt otherwise it bases it off current time (sha1 is not one of these though). Yay for random passwords -_-.
You may want to consider fetching your query using the username as the criteria, following a check against the password. The advantage is you can now determine whether it is the username or username/password combination that is the problem. This is more of an aesthetic thing as its not really required however.

Another thing to check which some people never think of - ensure that your passwords field is capable of storing 40 characters, either as a char or varchar should suffice. If you set it at 32 which is more common, you will lose the last eight characters which would of course not match the criteria you are feeding it. I know, I know, but you would be suprised how common shortened and truncated data is the cause of problems.

StupidRalph
01-17-2008, 07:07 PM
I'm with ralph on this one, ensure that the query is fetching the correct result set. Trying to remember off hand (ralph you may know off hand), but some of the algorithms require a salt otherwise it bases it off current time (sha1 is not one of these though). Yay for random passwords -_-.
I'm not sure if its based on time or not but crypt() automatically generates a salt if you do not provide one.


Another thing to check which some people never think of - ensure that your passwords field is capable of storing 40 characters, either as a char or varchar should suffice. If you set it at 32 which is more common, you will lose the last eight characters which would of course not match the criteria you are feeding it. I know, I know, but you would be suprised how common shortened and truncated data is the cause of problems.
This happened to me about 2-3 years ago. :o And you nailed my scenario exactly too. I was trying to store 40 characters in a field with a limit of 32.

Fou-Lu
01-17-2008, 07:26 PM
crypt is one yep, only bother using that if its for linux administration.
Yep, got caught on the same field thing, took awhile to figure out too -_-

Bob42
01-18-2008, 04:48 AM
Another thing to check which some people never think of - ensure that your passwords field is capable of storing 40 characters, either as a char or varchar should suffice. If you set it at 32 which is more common, you will lose the last eight characters which would of course not match the criteria you are feeding it. I know, I know, but you would be suprised how common shortened and truncated data is the cause of problems.

Yes! That was it! It works now. Thanks.

One thing that I am trying to do now is to make my login form and sessions as secured as possible from any hackers. I've already wrapped mysql_real_escape_string(); around my variables. I also took Jon W's suggestions and placed a if/else condition to check if the data has been submitted and that data actually exists in $_POST['username'] and $_POST['password']. For sessions, I have a session_start(); at the top, and I use $_SESSION['username'], etc throughout some of my pages. What else do I need to do to make my login system secured?

Fou-Lu
01-19-2008, 06:35 AM
Hmm, datatyping your code if logical is a good one to do. That is, if you ever have input that isn't a string (phone numbers, ages, etc), either cast them to the correct formats (int, float, etc), or regexp them to ensure they are proper values.
If you want to use sessions (a common feature of sites of course), whether they are predefined (_SESSION based) or if they are user defined, you can enhance your security by forcing the browser to accept cookies only - this removes the appearance of a session identifier, which with improper checks can be easily hijacked.
On that, ensure that you are also storing the user's IP Address (its hard to get the MAC, but I have scraped a Windows IIS to do it before - at an extreme overhead - but good for banning) and browser info in the session as well. Make sure you also check that the current session ip and browser match that supplied by the current browser.
Security is a tough topic, no matter how hard you try you can never by 100% certain that the user is who they claim to be with php.
Hope that helps you with some additional insight as well!

Bob42
01-19-2008, 11:00 PM
If you want to use sessions (a common feature of sites of course), whether they are predefined (_SESSION based) or if they are user defined, you can enhance your security by forcing the browser to accept cookies only - this removes the appearance of a session identifier, which with improper checks can be easily hijacked.
Hmm...I assume something like setcookie(); would do the trick for that. So something like:



setcookie("user", "$_POST['username']", time()+7200);




On that, ensure that you are also storing the user's IP Address (its hard to get the MAC, but I have scraped a Windows IIS to do it before - at an extreme overhead - but good for banning) and browser info in the session as well. Make sure you also check that the current session ip and browser match that supplied by the current browser.

Would something like this work? In my user authentication script, I would have a session set for the user's ip and browser information. Then in one of my pages, I would check whether or not they match.



if (!isset($_SESSION['ip']) || $_SESSION['ip'] != $_SERVER['REMOTE_ADDR'] || !isset($_SESSION['browser']) || $_SESSION['browser'] != $_SERVER['HTTP_USER_AGENT']) {
echo "Unathorized user!";
exit;
}

Fou-Lu
01-19-2008, 11:39 PM
Exactly the right idea.
As for the cookies, they are set by default by using the predefined sessions. The trick to it (if you want to force it), is one of two routes:
1. Set the ini value to force cookie use:


ini_set('session.use_only_cookies', 1);

2. Just check to see if the session value is set in the cookie as well:


if (!isset($_COOKIE[ini_get('session.name')]) || $_COOKIE[ini_get('session.name')] != session_id())
{
// This is the NO cookies set
}

I cannot recall off hand if the session_name() function can be called within an already started session or not, so I went with the ini_get instead. It has been awhile since I've used the predefined sessions in PHP, but this looks about right.

Bob42
01-19-2008, 11:57 PM
So do I just copy those two codes into one of my pages? Is session.name and session.use_only_cookies suppose to be replaced with anything, or is that how it's suppose to normally be?

Fou-Lu
01-20-2008, 12:00 AM
Those are the actual values to use.
Frankly, I'm lazy so I'd go with the first option and just a message on the primary pages saying cookies are required.
The second option is more along the lines if you want to inform the user that they must use cookies in any given situation.
I was more suprised to see that the default configuration for the use_only_cookies is already set to 1. I have a feeling that most servers disable that one and allow whichever route since sessions are so popular.



EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum