Jump to content
  • Checkout
  • Login
  • Get in touch

osCommerce

The e-commerce.

Upgrading Password functions to native php 5.5+


John W

Recommended Posts

As of Php 5.5 and higher there are very strong password functions built in that are the recommended method of handing passwords.  After seeing Burt's post on
https://github.com/gburton/Responsive-osCommerce/issues I decided to work on implementing it. You should read more at http://php.net/manual/en/faq.passwords.php where there is some great info if you're interested.  It explains why we should do this.  

On a current OSC site the password is being hashed and stored something like this
$P$DR08dUINt6wXeu5R5TmaJGluO9toq80
and after upgrading to Php native hashing functions it will be something like this
$2y$10$iI3eIn44i71QFq0oi0Dh3emM4Syvvd9/dxVCq22oVa6HnKxjOzeiy
which is much stronger for more reasons than just length.  

First, I test everything on my local machine (test server) with the help of the NetBeans IDE (free). Before putting this on your live site test it first although I do have it running on my live site using Php 5.6.  

Assuming you are running Php 5.5 or higher and you are using a current BS version this should be pretty easy.  All customers that have passwords hashed with the older systems will be automatically updated when they log in.  There are only two files to change and a sql statement to execute.  Note that the current password field setting of VARCHAR(60) will work now but may be a problem going forward.

 

On includes/modules/content/login/cm_login_form.php around line 58 find

            if (tep_password_type($customer['customers_password']) != 'phpass') {

change to

            if (tep_password_type($customer['customers_password']) != 'phpnative') {

replace includes/functions/password_funcs.php with this file

<?php
/*
  $Id$

  osCommerce, Open Source E-Commerce Solutions
  http://www.oscommerce.com

  Copyright (c) 2010 osCommerce

  Released under the GNU General Public License
*/

////
// This function validates a plain text password with a
// salted, phpass password or native php 5.5 and higer password hashing
  function tep_validate_password($plain, $encrypted) {
    if (tep_not_null($plain) && tep_not_null($encrypted)) {

      if (password_verify($plain, $encrypted)) {
        return true;
      }

      if (tep_password_type($encrypted) == 'salt') {
        return tep_validate_old_password($plain, $encrypted);
      }

      if (!class_exists('PasswordHash')) {
        include(DIR_WS_CLASSES . 'passwordhash.php');
      }

      $hasher = new PasswordHash(10, true);

      return $hasher->CheckPassword($plain, $encrypted);
    }

    return false;
  }

////
// This function validates a plain text password with a
// salted password
  function tep_validate_old_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 encrypts a phpass password from a plaintext
// password.
  function tep_encrypt_password($plain) {
    return password_hash($plain, PASSWORD_DEFAULT);
  }

// This function returns the type of the encrpyted password
// (phpass or salt)
  function tep_password_type($encrypted) {
    if (preg_match('/^[A-Z0-9]{32}\:[A-Z0-9]{2}$/i', $encrypted) === 1) {
      return 'salt';
    }

    If (substr($encrypted, 0, 3) === '$P$') {
      return 'phpass';
    }

    return 'phpnative';
  }

Run this sql statemnent in phpMyAdmin.  This isn't mandotory at this time but could/will be in the future.

ALTER TABLE `customers` CHANGE `customers_password` `customers_password` VARCHAR(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL;

You can check by using a test account to make sure the password changes format.

Post sny problems or questions and I'll try to help.  Assuming this goes well and is well received we'll work on the admin password functions, which should be simple.

 

I'm not really a dog.

Link to comment
Share on other sites

  • 10 months later...

Thanks for this.  Appreciate it.

 

While it works, and updates new passwords and password resets to use the stronger encryption, I did not find that it updates passwords on login.

I'm using this with BS 2.3.4

Link to comment
Share on other sites

The only thing I can think is that you didn't change ncludes/modules/content/login/cm_login_form.php, but other than that it should update passwords on login.  It's been a while since i was working on this but I tested it pretty well and I've been using it for a year now.

I'm not really a dog.

Link to comment
Share on other sites

Yes, that's all there was.  I haven't kept up with all the changes to BS 2.3.4, but I don't think they've changed anything that would prevent it from working.  It's been a year since I did this though, and it's not as fresh in my mind.

I'm not really a dog.

Link to comment
Share on other sites

I think to have the password updated on login you also need to change line 42 in login.php from

           if ( tep_password_type($check_customer['customers_password']) != 'phpass' ) {
to 
 
           if ( tep_password_type($check_customer['customers_password']) != 'phpnative' ) {
Link to comment
Share on other sites

When I looked in my database, old passwords were being updated on login.

I don't know, maybe i could be wrong but i thought  that it is considered a very bad security practice to directly store user passwords in a database, even if the database is encrypted?

Link to comment
Share on other sites

I don't know, maybe i could be wrong but i thought  that it is considered a very bad security practice to directly store user passwords in a database, even if the database is encrypted?

 

In general terms, you have to store passwords somehow. Hashing (or encrypting) is the process of making them unreadable even if someone gains access to your database.

What is generally considered bad is to store them un-encrypted as plain text.

 

What is also generally avoided is storing credit card numbers even when encrypted.

Link to comment
Share on other sites

In general terms, you have to store passwords somehow. Hashing (or encrypting) is the process of making them unreadable even if someone gains access to your database.

What is generally considered bad is to store them un-encrypted as plain text.

 

What is also generally avoided is storing credit card numbers even when encrypted.

Thanks for replying! It is always helpful when one can learn a thing or two from clarificaton.

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...