Where to store password encryption logic?

Not for 'how-to' coding questions but PHP theory instead, this forum is here for those of us who wish to learn about design aspects of programming with PHP.

Moderator: General Moderators

Post Reply
User avatar
allspiritseve
DevNet Resident
Posts: 1174
Joined: Thu Mar 06, 2008 8:23 am
Location: Ann Arbor, MI (USA)

Where to store password encryption logic?

Post by allspiritseve »

Hello all,

I'm working on a simple auth and staff management system. For security, I am storing passwords as an md5 hash of the username and password concatenated together. I am not sure where the logic to encrypt the password (for logging in, adding, and editing accounts) should go.

Logging in would be the easiest example. I currently have a LoginController that does this:

Code: Select all

$conditions = array (
    'username' => $this->request->username,
    'password' => md5 ($this->request->username . $this->request->password)
    );
    
$user = $this->userGateway->fetch ($conditions);
This was the simplest way I could code the login, but now that I am writing the insert and update functionality, I feel like the controller should just be passing the username and password without encryption. Should my userGateway (simple Table Data Gateway) be responsible for encrypting the password when selecting, inserting, and updating? I also feel like the gateway shouldn't be responsible for that, so I'm a little lost. Any ideas?

Thanks,

Cory
alex.barylski
DevNet Evangelist
Posts: 6267
Joined: Tue Dec 21, 2004 5:00 pm
Location: Winnipeg

Re: Where to store password encryption logic?

Post by alex.barylski »

1) Why has the username and password? Password is enough.
2) You should use sha256 or other -- md5 has been proven to be less than ideal.
3) Your model.
User avatar
allspiritseve
DevNet Resident
Posts: 1174
Joined: Thu Mar 06, 2008 8:23 am
Location: Ann Arbor, MI (USA)

Re: Where to store password encryption logic?

Post by allspiritseve »

1. Should my database ever be exposed, a hacker could check all passwords against a rainbow table. Hashing the username and password means the rainbow table would have to be created for every user individually, thus making it more difficult to find a match.

2. I'll look into that. Is it a simple function or more complex?

3. When you say "your model" do you mean my gateway? I have done a lot of searching on this topic, and most people say the logic belongs in the model, but given how so many people disagree on MVC definitions, I always feel like that is too vague of an answer. Could you explain to me why this logic belongs in the UserGateway?

Thanks,

Cory
User avatar
Maugrim_The_Reaper
DevNet Master
Posts: 2704
Joined: Tue Nov 02, 2004 5:43 am
Location: Ireland

Re: Where to store password encryption logic?

Post by Maugrim_The_Reaper »

1. I would suggest revisiting how you salt passwords for a few reasons. The main one is that since the usernames are presumably in the clear on the database, there's no reason to not take it a step further and introduce a computationally prohibitive hash. Essentially every new bit added to a salt doubles the additional processing time and storage needs for a new table. Let exponential math do the rest ;).

2. SHA256 is ideally available widely for PHP5 using the hash function. PHP4 unfortunately won't have built in SHA256 support as standard - so you might be stuck with MD5 and SHA1. Work with what you have though - salting makes even MD5 less vulnerable than by itself. Also never get the idea of multiple hashing - doesn't work since hashing is designed to execute fast so multiple hashing does almost nothing to the computational cost of restating rainbow tables.

3. Watch the responsibilities. Data retrieval and ordering should be managed by a Model/Gateway/Mapper, authentication calculation by a separate Authentication library/class-family, etc. Have a look at what Zend_Auth and Zend_Db are split in the zend framework manual for example.

Finally very few people dispute the definition or interpretation of MVC actually - usually there is the issue of how the component parts are implemented inside an MVC structure. :) For example ZF uses Zend_Db (TableDataGateway), Rails uses ActiveRecord, Symfony uses a full ORM like Propel, etc. Decisions within MVC is highly variable...
User avatar
allspiritseve
DevNet Resident
Posts: 1174
Joined: Thu Mar 06, 2008 8:23 am
Location: Ann Arbor, MI (USA)

Re: Where to store password encryption logic?

Post by allspiritseve »

1. The point of adding the username in the salt is to make individual user's passwords different even if their password is the same-- I could generate a random salt and place it in the database alongside the password, but I figure if they have access to the database, there's not much difference between them. It's easier to implement hashing with the username though, so I figure it's as secure as I need it to be right now.

2. I have php5, so I'll check out SHA256.

3. That's exactly why I was confused-- I didn't feel like it was the controller's responsibility or the gateway's responsibility to implement the authorization. I will see if I can work out an intermediate auth class to take care of it.

4. Maybe this forum is different, but I have been on sitepoint for a while, and even if you just take a look at the MVC thread in the application forum, there really is no agreement on any explicit definition of MVC.
User avatar
Mordred
DevNet Resident
Posts: 1579
Joined: Sun Sep 03, 2006 5:19 am
Location: Sofia, Bulgaria

Re: Where to store password encryption logic?

Post by Mordred »

(Re: 1) Add a site-wide salt besides the per-user salt. viewtopic.php?t=62782

The exact salting-and-hashing is an implementation detail that belongs to the model. The Controller should just pass username and password as they came from the user.

...->userGateway->fetch($username, $password); looks simpler / better.
Post Reply