I have read many articles advising me to use OpenID, including on Stack Overflow, for authentication. Unfortunately I can't use OpenID because my auth is not based on an email - it is based on a username and password.

Currently I am doing authentication like this:

  1. User enters username and password.
  2. If the user login is successful then insert useragent, IP and an unique key which I create into a database.
  3. Set the unique key in a cookie and transmit it to the user.
  4. Whenever the user clicks any link (opening a page) all of the three are matched. If any match fails they will be logged out.

I create the unique key by encrypting time stamp + ip + useragent + username many rounds with MCRYPT_RIJNDAEL_256.

All connections are made using TLS to avoid sniffing.

Is this type of auth secure from session hijacking, or should I alter this method?

  • 1
    Why is your application required to ignore modern authentication theory? Why are you tied to username/password? What are the consequences of failure? – Mark C. Wallace Mar 4 '14 at 15:50
  • @MarkC.Wallace what do you mean by modern auth theory can you explain ? what are the consequences of failure(i didn't understand this one). – CS GO Mar 4 '14 at 15:52
  • @MarkC.Wallace I would love to use OpenID and i am ready to use it but the problem is majority of the OpenIds are connected/linked with an email address. emailid auth is what i don't want !!! – CS GO Mar 4 '14 at 15:58
  • @MarkC.Wallace consequences of failures are you referring to forgotten password / resetting password ? – CS GO Mar 4 '14 at 16:02

You know what you shouldn't do? Reinvent the wheel.

There are many authentication libraries out there, especially for PHP. Almost every single framework includes one. Use it. If you aren't using a framework, stop what you are doing and use one!

And yes, you must use TLS for your site.

| improve this answer | |
  • can you suggest some libraries ??? – CS GO Mar 4 '14 at 13:00
  • No, I don't know PHP well enough to have confidence in any one library. – user10211 Mar 4 '14 at 13:02
  • session is hijack able OR not ? – CS GO Mar 4 '14 at 13:27
  • Everytime you reinvent the wheel, especially in cryptography, there's a high chance your code is going to present vulnerabilities. If I were you, I'd just consider your protocol to be too weak [or anyways not as strong as current technology allows it to be]. – Giulio Muscarello Mar 4 '14 at 17:32

You should never roll your own. There is a so called "Schneier Law" that states:

Anyone, from the most clueless amateur to the best cryptographer, can create an algorithm that he himself can't break.

That means that even after you fail to break your own scheme, an expert my break it in two seconds. Have a look to this Schneier article.

There are thousands of methods working and you should use them, many of them have been tested by crypto and security professionals.

Also, you should read this Q&A.

| improve this answer | |

I can't use openid because my auth is not based on email id

OpenID does not depend on e-mail—an OpenID identity could be something like someone.example.com.

Then insert ( useragent, ip, unique key which i create ). into a database.

It is unwise to tie your sessions to IP address. Some users' IP addresses will legitimately vary (for example because they are behind a proxy cluster, or are switching between mobile networks). Kicking them out on IP change would make your site very difficult to use for a subset of your audience.

Matching IP is in any case of very limited usefulness. The usual attack it is attempting to address is that of session token leakage and reuse from an attacker client. But possible causes of token leakage are generally those that give the attacker access to make requests from the client anyway (XSS, client-side malware, bad transport security) or those which are already catastrophic (database compromise, server code execution).

Similarly User-Agent matching is of little value as the UA string isn't any kind of secret and is easily spoofed. Matching IP and UA can be of some worth as just one input to a complex risk rating system with behavioural history, but primitive matching is ineffective as a security measure and likely to cause you more damage from false negatives than benefit.

Time stamp + ip + useragent + username and encrypt them many rounds = unique key !

Encrypt type = MCRYPT_RIJNDAEL_256

Then insert ( useragent, ip, unique key which i create ). into a database.

set the unique key in cookie and transmit it to user.

As the client-submitted ‘unique key’ is verified simply by comparing it against the known value in the database, its actual content is of no relevance and there is no point in generating it in such an elaborate way.

A string of random data would do just as well for this, and then what you'd have would be functionally equivalent to the normal way people do logins in PHP: by putting a logged-in-user-ID on the session. Re-using PHP's standard random-PHPSESSID-based sessions would have advantages in terms of performance and the well-understood nature of their configuration.

There is another somewhat-common model of authentication, which may be what you were thinking of with the ‘unique key’ idea. This is where you create a token based on items you want to authenticate (typically user ID, password/reset generation numbers and token expiry time) together with a cryptographic signature over those items (typically HMAC) using a server-side secret key. The server can recognise and authenticate the incoming token using that signature, giving it the advantage that it doesn't need any persistent database/session storage. But unless you need that particular property I would stick with plain old sessions.

i think using TLS is must here

Yes. And remember to give your cookies the secure flag so they don't leak through a non-TLS request.

| improve this answer | |
  • 1. If a website is providing you a openid they do it after email auth . 2.so you are suggesting that i should use simple phpsession cookies as my only auth ? – CS GO Mar 4 '14 at 15:09
  • 1. There's nothing in OpenID that requires e-mail at all. Some identity providers have links to e-mail, some don't. 2. Yes. Store the user's ID on the server-side session and retrieve it on each request. (If you want a hard timeout then you can also store an expiry timestamp in the session too and refuse to accept the session if it is too old.) – bobince Mar 4 '14 at 15:21
  • store it like this ? $_SESSION['username'] = 'superman'; – CS GO Mar 4 '14 at 15:28
  • That would work. The implication of storing username is that users are identified in your system purely by username. A consequence of this model is that users can never be renamed or deleted. That may or may not be true for your application. A more typical alternative is having unique-forever user IDs (surrogate primary key in database). – bobince Mar 4 '14 at 15:33
  • yeah i use both of them surrogate key(which is always unique) and username(provided by user) – CS GO Mar 4 '14 at 15:35

The answers above that suggest not to reinvent the auth'ENTIC'ation wheel are completely missing the point that you are creating an auth'ORIZ'ation token. The best wheel for authorization tokens I think would be to use something like HMAC+SHA2.

Minor nit, don't use timestamp of creation but a time the token will expire. And if possible, don't use the login unless you really really need it. The principle of least privilege should apply, so in order to create an authorization token for a business logic REST servicew that has no need for a username, don't supply it and don't include it in the auth token generation.

So you will end up with something like:

authkey = base64(hmac(sha224, concat(expiretime, ip, useragent), secretkey))

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.