PHP Encryption and Remember Me

Programmers, or at least those serious about security and encryption, will tell you that the only way to be secure is not have a remember me function anyways. In addition to that, you would also not have a reset password functionality either.

But we all know in today’s world, you almost have to have it for user convenience and leave it up to the user to hang themselves. I’ve seen some blog posts advocating for using a program like LastPass or KeePass but be honest, would you even recommend that to a user who you really want to get used to using your system and not another password system before they can even use yours?

Where am I going with this?

Tonight, I did some light reading (heh) on cryptography and implementing a remember me function and I thought I would pass along this thought nugget. Now, me personally, without reading I have been able to implement remember functions by using expiring tokens linked to the user id of people. The problem with this of course is storing the user id in the cookie.

The same thing can be said for reset password functionality, although on much shorter time span.

But I came across something tonight which alleviates some of the fear of storing user id’s in cookies and brought up something else I didn’t even think of at the time.

The most robust way I could find of storing remember tokens was a 2 part process. After login, create a selector and token of random bytes using openssl_random_pseudo_bytes of course that are linked to the user id. But you never store the user id in the cookie. Instead the cookie itself stores a combination of selector:token in plain text. In the database, it’s stored as selector and then a hashed version of the token. It was recommended to use sha256 but I actually went ahead with PHP’s password_hash function.

Of course, to look it up, you split everything up, check the hash to make sure it expires or in my case, I have functions that clear our the hash content upon expiration automatically as part of the db. And of course, make sure to set your cookies to expire as well and when they do, make sure they die 🙂

This has the benefit of not storing user id’s, mitigating the time attacks associated with the “randomness” of openssl and if your hash table was compromised, the validator tokens would be hashed, preventing a mass attack on all users. Let me know if you think there are improvements there or want clarification, but I thought it was pretty neat and as always, no one cares about security until it effects them. Be proactive!