Helpful Information
 
 
Category: Security and Cryptography
Hashing passwords

I'm creating a database that will store usernames and passwords for use with a user authentication system. I've read about hashing passwords, and it seems like a good idea, especially since the database will not be highly secure in general.

If you hash the passwords, and someone forgets theirs, what are you supposed to do? Are you supposed to keep a record of the plaintext passwords separate from the database? Do you have to just make up a new password?

Since hashing passwords etc mostly is a one way street, the easiest thing is to have a function that generates new passwords. If you use some sort of algorithm to encrypt/decrypt your passwords, and that gets cracked, your passwords will be wide open...
Maybe you could have an additional field in the db where the user can store a hint to their password. If they forget their password, show them their hint. If they still can't figure it out -> generate a new password.

/NoXcuz

Why are you helping this jerk?

Well, I've just read the thread which I assume you refer to when saying that, freebsd. And I see your point now...
But since I haven't participated in the thread and thus haven't been offended myself (yet? ;)), I prefer not to take a stand in that particular case. I'm not saying I don't have an opinion, but I just try to keep it to myself until I'm convinced otherways.

And I don't think flame wars contribute to anything meaningful...

/NoXcuz

And I don't think flame wars contribute to anything meaningful...


True indeed.



have a function that generates new passwords


Here's the deal: I am developing this site for a client. There are approximately 1700 members of the client's organization that are supposed to have access to this private area of their website. These members are not computer savvy. I highly doubt a password that is generated at random is going to work out for them. It might be the thing to do initially, to avoid assigning or inputting 1700 passwords, but I believe they will need to make up their own password. So, in that context, would you say that the procedure should be:

1) user / administrator created password hashed into database
2) user forgets password
3) user / administrator creates new password
4) new password hashed into database

Do you think hashing the passwords is even a good idea? This site is not top-secret, the passwords are not protecting a database of credit card numbers or anything like that.

Thanks for your advice.

I would hash them anyway, coz I wouldn't wanna know or have access to all of their passwords. Of course security is much, much more than just hashing passwords, but it's at least a step in the right direction.
To reduce the amount of time you might need to spend on helping users remember their passwords or assigning them a new one, I would try to automize as much as possible. And that includes having a function that generates new hashed passwords. Preferably using the md5() function or something similar.
I would do something like this:

1. Admin creates hashed password (with a pw-generating function & a loop) and stores that in the db.
2. Mail the users their passwords.
3. Allow them to change their passwords to something that's easier for them to remember.
4. (optional) Have a field where they can enter a hint to their password.
5. In case of forgotten password -> mail them their hint.
6. Still don't know their password -> generate a new one with the mentioned function and mail that to the user. Maybe you could just have a form that lets them enter their username/name, and then generates the new password and mails that to them.
7. Allow them to change the password.

And the circle is complete...

If you're using PHP & MySQL, I remember seeing a function in the PHP forum that generates random md5() passwords a while ago. Might be worth checking out...

/NoXcuz

Ok, that all makes sense. I'll take a look for that function. I assume these passwords will just be a random sequence of alphanumeric characters, probably of a fixed length.



1. Admin creates hashed password (with a pw-generating function & a loop) and stores that in the db.
2. Mail the users their passwords.


I just have to make sure to mail them the password before I hash it into the database, right?



Of course security is much, much more than just hashing passwords, but it's at least a step in the right direction.


It seems that you know more about this than I do (really, if you know anything about it, you know more than I do), so maybe you could comment on the system I have set up, in a general sense. I have the user enter their username and password in a form, which is submitted over an HTTPS connection (though you wouldn't believe what you have to go through to find that out). The FORM's action calls a PHP page that queries the username – password database (which so far has not been hashed, and only has one username and password for testing purposes). If the username and password submitted match a record in the database, a session cookie is stored in their browser (something like authorized=yes). (By the way, I test to see if the cookie is sucessfully placed, and alert the user if it is not.) They are then shown a link to the private area of the site.

I created the site with a single PHP "template" that uses include() to display the content. So, the very first thing in this template is a test for the presence of the cookie. If the cookie is not there, I write a header that redirects them to the homepage, otherwise everything proceeds as normal.

Does that sound like a decent system? Also, would it be a good idea to hash the username itself?

This is what was thinking about. A random password generator, which I found during a search. Just feed it with the length of your password, and it'll return something random...



<?php
function randompassword ($length) {
mt_srand ((double) microtime() * 1000000);
$possible = '0123456789!@#$%^&*()_+' .
'abcdefghijklmnopqrstuvwxyz' .
'ABCDEFGHIJKLMNOPQRSTUVWXYZ' ;
$str = "";
while (strlen($str) < $length) {
$str .= substr($possible, mt_rand(0, strlen($possible) - 1), 1);
}
return($str);
}
?>

Here's your random password: <? echo randompassword (5); ?>


BTW, I found this article somewhat enlighting when dealing with encryption: http://hotwired.lycos.com/webmonkey/backend/security/tutorials/tutorial1.html

And yes, you'd better mail the user their password before you hash it... ;)

Let's assume that you use md5() to store your encrypted passwords in the db. You'll then have a form, something like this:


<form action="https://www.mysite.com/chkuser.php" method=POST>
Username: <input type="text" name="username"><br>
Password: <input type="password" name="password"><br>
<input type="submit" name="submit" value="Submit">
</form>


And on the recieving end, chkuser.php:


<?
$encryptedPassword=md5($password);
$query="SELECT username
FROM users
WHERE username = '$username' AND password = '$encryptedPassword'";
$result = mysql_query($query, $con) or die ( 'Couldn't access db...' ); // $con holds the db connection
$num = mysql_numrows( $result );
if ( $num != 0 ) {
$auth = true;
// Successfully authenticated...
} else {
// Failded validating user, so try again...
}
?>


When Admin is inserting/updating the passwords in the db:


<?
$password=randompassword(5);
$encryptpw=md5($password);

$query="UPDATE users SET password='$encryptpw' WHERE userid=6";
$result = mysql_query($query, $con) or die ( 'Couldn't access db...' ); // $con holds the db connection
if ($result) {
mail("users_email@somewhere.com",
"New password",
"Here is your new password: $password\r\nRegards\r\nAdmin@mysite.com",
"From:admin@mysite.com");
} else {
echo "failed...";
}
?>


I just threw this together, so don't take it literally...

Setting a cookie upon a successful login is reasonable. But that can be spoofed by a user who just creates his/her own cookie if you just set authorized=yes or similar. And some users disable cookies...
So I prefer sessions AND cookies, and have a validating function which is called on every page that compares a sessionvariable (or a cookie value) to what's stored in the database.
If you store both username and password in the cookie, I would probably use md5() on both stored values. And you could store authorized=md5('yes') in the cookie to make it a little harder...

The flow of your code seems decent, so I just threw you some ideas...

/NoXcuz

Yeah, excellent, thank you.

If you're sick of reading about my project, you can feel free to skip this post as it is really just commentary on your last post.

That function will give me a great head start (I'll write my own, even if it's almost the same because I mostly like to write my own code, and I'll learn more, plus I'll definitely be taking out the symbols, that would go way over the users' heads). I actually had already seen the webmonkey article, which I found very enlightening. That was probably what gave me the idea to has the passwords. I don't know if you've looked at any of my other threads in this forum, but I need to find a way to send a form submission in an encrypted email, and that article really helped me out with that idea, though I have yet to implement it.



I just threw this together, so don't take it literally...


Got you.



Setting a cookie upon a successful login is reasonable. But that can be spoofed by a user who just creates his/her own cookie if you just set authorized=yes or similar


I thought about that. I supposed that it would be somewhat more dificult to do so because I used a session cookie, but I don't know if that's actually true. Besides, I think they would need to breach the security in some other way before that could happen, like they would need to get into my account by telnet or FTP to look in the PHP that tests for the cookie to see what the value is supposed to be. Either that, or if they are a good guesser, never a factor to be underestimated.



And some users disable cookies...


Like I said, I test to see if the cookie is sucessfully placed, so the program will at least fail gracefully and alert the user about what has happened. So, I'm requiring cookies for this site.



So I prefer sessions AND cookies, and have a validating function which is called on every page that compares a sessionvariable (or a cookie value) to what's stored in the database.


All I know about sessions is that (I think) to use them you must propagate a session ID in the URL. I am already passing all sorts of variables in the URL to make my include() scheme work, and I don't know if I could handle the overhead of a session ID on top of that, though I did just learn the other day that you can set a path for PHP to search for include() files if they are not found in the current directory, which might be worth investigation.



If you store both username and password in the cookie, I would probably use md5() on both stored values. And you could store authorized=md5('yes') in the cookie to make it a little harder...


I'm currently not storing either in the cookie, as there are only two levels of access – allowed and not allowed – but I'll give it some consideration. I'm not sure what hashing 'yes' into the cookie would accomplish? Do you mean just so it isn't perfectly obvious what the value of authorized is?

Thanks again, you've been very helpful, I really appreciate it.










privacy (GDPR)