• 0

[PHP] My Method Of A Secure Login System


Question

I came up with a method I'm sure is in use somewhere else, but I was just wondering if any of you either used this before, or know of any flaws with this method. Right now I'm working on creating a content management system, and wanted to create the most secure method to login over HTTP.

What I came up with is this:

1. User requests the login page

2. Server generates a random string, sets it in $_SESSION

3. This string is sent to the client's browser in a hidden <input /> tag.

4. When the user logs in, two things happen: First, the SHA1 value of their password is calculated. This value is then appended to the random string from the hidden input, and the SHA1 value of that entire string is taken again. (So the string looks like this - password = sha1(sha1(password) + rand_string) - this is all done client-side, with JavaScript.

5. Now the server has three inputs from $_POST - the username, the double-encrypted password, and the random string. The server first locates the administrator username on the user table, then takes the password (stored as an SHA1 value), and adds the random string to it, and gets the SHA1 value (similar to what was done in JavaScript above). Then it's a simple comparison.

6. For some additional security, the value of the random string is also checked against the $_SESSION variable. Each login attempt clears this variable as well - so the user must continually request the form each time.

Thoughts?

Link to comment
Share on other sites

Recommended Posts

  • 0
Ah, well in your case you only support one confirmation at a time, so you're right, storing the action wouldn't help

If multiple confirmed actions are a design goal then I'd follow your approach, or some variation there-of.

Given that your e-mail change routine requires knowing the password (something I agree with) and a user that can't recall their password would be unable to log in to change their e-mail: I can't think up a good use case where simultaneous confirmation would be a desirable feature, but that could be my lack of imagination.

EDIT. I fixed my quote above: it was the wrong paragraph entirely.

Has anyone looked into thunder table attacks?

They're not applicable to what we're talking about and not particularly interesting either.

Edited by evn.
Link to comment
Share on other sites

  • 0

Is there any way for persistant local storage on a user's browser?

http://pablotron.org/software/persist-js/

I came across that - and if you just disabled the use of cookies in that engine, it would be easy to store a key on a user's browser and just use JavaScript to encrypt the session ID client-side to verify it server-side.

Or just have the user put in a common key on each page load client-side...

Link to comment
Share on other sites

  • 0
Is there any way for persistant local storage on a user's browser?

The only standard option is HTML5 local databases but the support for is about as bad as CSS animations.

If you're willing to deal with plugins then flash-cookies can work.

I came across that - and if you just disabled the use of cookies in that engine, it would be easy to store a key on a user's browser and just use JavaScript to encrypt the session ID client-side to verify it server-side.

Or just have the user put in a common key on each page load client-side...

This gets extremely ugly. Let's simplify a bit just using PKI signatures.

  • User logs in over standard HTTP password is sent plain text but verified on the server with standard-issue salted hashes.
  • During the log in process the client generates a PKI key pair (using javascript) and sends the public half to the server which stores it in the client's session. The private half is stored locally using html5 databases which are "reasonably secure" compared to http cookies.

When you come to a page that requires the user to be authenticated:

  • User requests the page - including plain-text session id in the form of cookie data or query parameter
  • You respond with the page - along with some javascript that says "Hey, take your session ID, add this random string, sign the whole thing and send that back with an AJAX request" (maybe it even encrypts the random string using the public key) - not that it matters.
  • User does the above - server verifies the signed message using the public key generated during the login process

The problem with the above is that you have basically just re-implemented https requests in javascript but with crumbier performance (every request must happen twice), much more fragile (storing the key locally is troublesome), and less compatibility (won't work on blackberry phones). Not to mention the whole application gets much more complicated because you now need to queue actions and then execute them only after javascript confirmation. And then if javascript breaks you've either got a site people can't use, or you have to fall back to something without 'real' security at all.

All of the above also doesn't protect assets like images/media/etc nor sensitive data displayed on the site (it wouldn't be suitable for display medical information for example).

If you need something to be secure and you can't afford a certificate: generate your own, make a page that explains how safari/firefox/ie users can trust the key to avoid the annoying "this key isn't trustworthy" messages and be done with it. It's faster, works better, and is orders of magnitude less likely to screw up.

Link to comment
Share on other sites

  • 0
If you need something to be secure and you can't afford a certificate: generate your own, make a page that explains how safari/firefox/ie users can trust the key to avoid the annoying "this key isn't trustworthy" messages and be done with it. It's faster, works better, and is orders of magnitude less likely to screw up.

I knew you were going to say that, for one simple reason... You're right.. My particular CMS only has one user - a site manager/administrator, so if it was for only me personally, I could implement something like I outlined for myself...

Unfortunately, I want something that works for everyone, as I want to release the CMS. I guess the standard session ID is the final go for that, for now.

Link to comment
Share on other sites

This topic is now closed to further replies.
  • Recently Browsing   0 members

    • No registered users viewing this page.