Page 1 of 1

Help with password validation

Posted: Thu May 13, 2010 1:55 pm
by CameronB
Hello,

I currently run a store utilizing oscommerce. I'm trying to create a php script which can connect to an installer app I have created and validate a customers username and password against the oscommerce database.

The simple test php script I have for plain text password verification is:

Code: Select all

// Connect to server and select databse.
mysql_connect("$host", "$username", "$password")or die("cannot connect"); 
mysql_select_db("$db_name")or die("cannot select DB");

// username and password sent from form 
$myusername=$_POST['myusername']; 
$mypassword=$_POST['mypassword'];

$sql="SELECT * FROM $tbl_name WHERE username='$myusername' and password='$mypassword'";
$result=mysql_query($sql);

// Mysql_num_row is counting table row
$count=mysql_num_rows($result);
// If result matched $myusername and $mypassword, table row must be 1 row

if($count==1){
echo OK;
} else {
  echo FAILED;
}

Now, the issue is with OSCommerce. It happens to use salt and an MD5 for passwords. The following is provided in OSCommerce:

Code: Select all

// This funstion validates a plain text password with an
// encrpyted password
  function tep_validate_password($plain, $encrypted) {
   if (tep_not_null($plain) && tep_not_null($encrypted)) {
// split apart the hash / salt
      $stack = explode(':', $encrypted);

      if (sizeof($stack) != 2) return false;

      if (md5($stack[1] . $plain) == $stack[0]) {
        return true;
      }
    //}

    return false;
  }

////
// This function makes a new password from a plaintext password. 
  function tep_encrypt_password($plain) {
    $password = '';

    for ($i=0; $i<10; $i++) {
      $password .= tep_rand();
    }

    $salt = substr(md5($password), 0, 2);

    $password = md5($salt . $plain) . ':' . $salt;

    return $password;
  }
?>

How can I integrate this encrypted password verification with the simple script I showed at the beginning? I have been trying this for hours, but each path I venture down fails to work. Any help is appreciated!

Re: Help with password validation

Posted: Fri May 14, 2010 7:02 pm
by mecha_godzilla
It looks like you just need to copy the two functions from the second script into the basic script (at the end would be the most convenient place) and then call the tep_encrypt_password(). In your basic script, you would need to amend it so it looks like:

Code: Select all

// Connect to server and select databse.
mysql_connect("$host", "$username", "$password")or die("cannot connect");
mysql_select_db("$db_name")or die("cannot select DB");

// username and password sent from form
$myusername=$_POST['myusername'];
$mypassword=$_POST['mypassword'];

$mypassword=tep_encrypt_password($mypassword);

$sql="SELECT * FROM $tbl_name WHERE username='$myusername' and password='$mypassword'";
$result=mysql_query($sql);

// Mysql_num_row is counting table row
$count=mysql_num_rows($result);
// If result matched $myusername and $mypassword, table row must be 1 row

if($count==1){
echo OK;
} else {
  echo FAILED;
}
You don't need the tep_validate_password() function because the passwords should be saved in your database in their hashed format anyway (MySQL does the matching for you.)

Having offered that suggestion though, you really do need to look at how tep_encrypt_password() works because it's calling a function that generates a random number that gets appended to the password - if you don't have access to this later on then your passwords (when hashed the next time) won't match the ones in the database (this also goes for the salt as well.) In a nutshell, if you're going to use a salt/random value then you need to save it somewhere so you can retrieve it at a later point - the password is like one half of the key while the salt is the other half.

If you don't fully understand how hashing/salting works then I would suggest you need to read up on this first, otherwise your script will be generating values that your logins won't match. Bear in mind that if you already have passwords in a database then you'll need to convert them so they'll work with your new system. Also, a couple of other points while we're being pedantic:

1. The use of the term "encryption" in the tep_encrypt_password() function is incorrect, because the hashing algorithm doesn't (or at least shouldn't) allow the retrieval of the original value (this is referred to as a "one-way" algorithm.) Bear in mind as well that if your user forgets their password there's really no way to retrieve it if the password is hashed - you have to authenticate them some other way and generate a new password for them (this is usually done by emailing it to them based on the email address they provide matching the one in your database.)

2. There has been lots of feedback about MD5 not being as great as it was, so you might want to consider using SHA256 or a stronger hashing type if your server supports it. In a general sense, there's no real difference in how quickly hashes are generated between MD5 and SHA256 so try and go with the stronger one.

If you need any more info about this please say so! Without wish to be a boring old killjoy, you need to remember that your login script (if poorly written) could easily compromise the integrity of your ecommerce site (especially so if you hold payment details or allow any sort of "one-click" purchasing) so always try and get some proper feedback on your scripts before deploying them.

HTH,

Mecha Godzilla