Forum Moderators: coopster
Been designing and coding a long time but have only recently started messing with encryption. Let me briefly describe the problem:
I am storing passwords in a MySQL database as MD5 hashes. If a person loses or forgets their password, I need to be able to create a new password and email it to them with the click of a button. Seems simple enough, but for some reason the emailed password is not matching the stored hash.
I did notice in this process that the input fields for initial registration and login had to be identical in size or it changes the MD5 hash; i.e. <input type="password" value="pswd" size="12" maxlength="12"> for both usages.
However, in order to create the password with the click of a button I have a function that is creating the password, updating the database, and sending the email with the new password. Since I discovered this prior issue I thought that logically the password length being created should also be 12 characters. No matter what size I alter the creation function to, it fails. Please help me! My head is bloody from banging it against the keyoard lol
*************************************
Here is the function:
*************************************
function generate_password($length=8) { // note when in use I am passing a length of 12 (see below)
$password = "";
mt_srand ((double) microtime() * 1000000);
$char = "A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,T,U,V,W,X,Y,Z,a,b,c,d,e,f,g,h,i,j,k,m,n, o,p,q,r,s,t,u,v,w,x,y,z,1,2,3,4,5,6,7,8,9";
$char = explode(",", $char);
$n = count($char);
while (strlen($password) < $length) {
for ($i=0; $i<$n; $i++) {
$r = mt_rand(0, $n-1);
$temp = $char[$i];
$char[$i] = $char[$r];
$char[$r] = $temp;
}
$r = mt_rand(0, $n-1);
$password .= $char[$r];
}
return $password;
}
function update_password() {
$new_password = $this->generate_password(12);
$query = "UPDATE TABLE_NAME SET password=MD5('$new_password') WHERE EMAIL='$email'";
mysql_query($query);
if (mysql_errno()) {
$this->ERRSTR = "Could not update password (".mysql_error().").";
return;
}
$subject = "Your New Password";
$headers = "From:user@somewebsite.com\r\n";
$body = "
Your pasword has been reset!
Your new password is:
{$new_password}";
mail($email, $subject, $body, $headers);
return 1;
}
[edited by: dreamcatcher at 7:25 am (utc) on Oct. 12, 2007]
[edit reason] Fixed side scroll. [/edit]
$query = "UPDATE TABLE_NAME SET password=MD5('$new_password') WHERE EMAIL='$email'";
try switching it to this:
$query = "UPDATE TABLE_NAME SET password=MD5($new_password) WHERE EMAIL='$email'";
At first glance it looks like you've been storing the MD5 of "$new_password" instead of the variable.
$char = "A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,T,U,V,W,X,Y,Z,a,b,c,d,e,f,g,h,i,j,k,m,n, o,p,q,r,s,t,u,v,w,x,y,z,1,2,3,4,5,6,7,8,9";
So after numerous attempts with these suggestions. I finally decided to make a test page that contained only the problematic functions. At first I had a problem with none of the hashes matching up; including the way I knew they had matched successfully.
After removing the single quotes from the MD5() functions. I got the test page to work perfectly in both scenarios.
So I attempted to apply this information to the page where I update the user's password with the generated one using:
password='".MD5($password)."'
It still did not work. So then I applied this same method to the login function and BLAM! It worked! WOOT!
Now here's the kicker...
The Admin page is still using: password=MD5('$password') as the login syntax and it works just fine. Even on the passwords that are generated. Additionally, the initially created password are sent to MySQL using:
INSERT INTO TABLE (password) VALUES (MD5('$password'))
and these passwords still work fine as well! I'm glad I got it to work but I am still mystified as to what the REAL problem is.
Is this an issue of the UPDATE constant sometimes corrupting information? Is this an issue of MD5 use within literal strings being unpredictable? Is this the real reason why I needed to make sure that the INPUT box sizes were identical?
Thanks to all who have helped, it was driving me bonkers, but I still don't get it. I've been reading up on MD5, but I can't find this kind of behavior really documented anywhere.
I've been using the syntax as previously stated for another part of these functions and have never had a problem with it. Creating and storing an authorization code using: auth=MD5('$auth').
Should I change it over to this syntax to be safe from future problems? Or if it ain't broke don't fix it?
P.S. I would still love to have any insight on the questions from the post above :)
#1 - Though you cast variables in any and/or all of the ways posted in this thread, using the same variable casting technique throughout your entire script avoids confusion (so tru thank u for that reply)
#2 - MD5 does NOT have different results for an identical string, so if this appears to be occurring, look for the answer somewhere else in the script
#3 - when using preg_match(), be certain that it is covering all of the necessary characters that could appear
When I tell you what happened you will laugh...I did, eventhough it drove me insane and after I cursed for 20 minutes lol
The problem was not in my variable declarations, or the functions I posted in this thread. It turns out that the problem was in my preg_match() function that was confirming the validity of the password being entered. It wasn't looking for capital letters. Magically once I added them in, everything worked like a charm. The reason I was having intermittent problems is because some of the MD5() conversions happened to be all lowercase, so I was just getting around the preg_match() problem by sheer luck. *sigh* I love coding lol
Hope this helps somebody else before it drives them as nuts as it drove me :)