Login over Unsecure Channels

Blog

Yesterday I talked about securing stored passwords in a database.  That is helpful in preventing an attacker from reversing user’s password information assuming they got access to your database.  But what good is protecting that information if your users login by passing their username/passwords over plaintext.

Now this whole process is assuming you use email address as the login identifier(otherwise just swap email for username or whatever). 

Let’s start by remembering the secured password method in the database from yesterday:

md5(lowercase_email + md5(password))

To protect your users from having their password sent in plaintext, the best method is to hash the value prior to submitting.  Since we are taking in the email address and password as login data, we can actually generate this hash in JavaScript and send only the result instead of the password.  We never have to pass the password at any point.

While this method is good, it’s not perfect.  Any decent attacker could perform a simple replay attack to authenticate against our application.  A quick fix for this would be to add a nonce (number used once).

Each login attempt should be preceded by a randomly generated nonce variable (usually 32 alpha-numeric characters) that is stored in Session data as well as user-side form data.  With this, the JavaScript executed on login can also perform this:

md5(nonce + password_hash)

The password hash is referring to the secured password method mentioned above.  This one-time hash can then be performed on the server side (as the nonce is saved in Session data) and the values compared.  Since a new nonce is generated each page load, reply attacks are impossible and your user can login over unsecure channels without a problem.

No Comments

Storing Passwords in a Database

Blog

The other day, a friend of mine was asking for the best practice regarding stored passwords in a SQL database.  His first idea was a simple hash (SHA1 in his case).  While this is significantly better than plaintext and even MD5, it is still computationally feasible to reverse/guess the values if the server was compromised.  Assuming a strong password of 12 characters (alpha-numeric and symbols available on a standard keyboard is ~95 possibilities) we have a max of 12^95 possibilities for passwords.  A rainbow table of MD5 and SHA1 lists can be downloaded without a problem, generating them takes significantly more time (but still feasible).

The next logical course of action would then be to include some sort of salt with the password.  This salt would have to be stored somewhere (to allow for password verification) and in the end would only slightly increase the amount of time required to guess the password (as new rainbow tables would have to be generated).

The best option, the same as I used in AreYouAG33k.com, would be to have layers of hashing with salts, example:

md5(lowercase_emailaddress + md5(password))

To brute-force reverse a single password, you would need to generate 32^16 rainbow keys of (32 + email) characters long just to get the md5 of the password for one user.  This is more powerful then a basic salt, frustrating to reverse, and incredibly easy to implement.

No Comments

Recent Work

Blog

Sorry for the huge gaps between posts.  I’m trying to find time to prepare and write up posts about my various projects.  The big one, that I hope can benefit lots of people, is my MySQL Advanced Class.  It’s basically a PHP class that allows static one-line access to MySQL with proper parameter binding and exception throwing. 

I’m shooting for finishing the write up tonight, but I’m terrible with timing.  :D

I’ve also started teaching a graduate level CS-640 Web Development with PHP/MySQL class at Sacred Heart University in Fairfield, CT.  This is the first time I’ve taught this class, but not my first time teaching.  So far, the students are doing quite well!

No Comments

Math CAPTCHAs

Blog

A few years ago, when I was sitting at my moving sale, I came up with some crazy variations on the basic word/letter based CAPTCHA for my senior project, SHUGamer.com.  Most of the ideas I had were either impossible to implement or difficult to answer.  I eventually decided to implement a system based on a simple mathematical problem converted into a word problem:

If you have two apples in one hand and three oranges in the other, how many fruit do you have total? 

This way, the number of variations would be very difficult (never impossible) for a bot to automate.  Because of the difficulty in translation (natural language processing), there wouldn’t be a heavy need for warping (annoying to a user).  The chances of guessing a correct answer are ~1/100 (not terrible odds, but decently bad for a bot).  Finally, the problem would have a clear answer (not trying to guess if it’s a 0 or a O) leaving less room for human error.  The resulting image looks like this:

CAPTCHA Example

This implementation isn’t perfect (nothing ever is), but it was a fun experience to build and can be easily added to any PHP based website.

PHP Mathematical CAPTCHA Class

Just so you know, SHUGamer.com and the later AreYouAG33k.com heavily relied on Adobe Flash, so visually disabled users wouldn’t be able to fully experience the site (sorry).  This meant I didn’t need to implement an audible option for the CAPTCHA.

No Comments

Facebook Puzzles

Blog

Hey, it’s been a while since I posted last.  After getting certified, I felt like I needed to push my programming skill further.  That’s where the Facebook Engineering Puzzles came into play.  I completed the first two training ones last August ("Hoppity Hop!" and "Meep meep!").  I also worked on the first easy puzzle, "Liar, Liar," but was unsuccessful in optimizing the solution to meet the requirements of the Puzzle Bot.  Finally, in March I had an epiphany and realized that I was going about the puzzle all wrong.  In less than a day I solved "Liar, Liar" in PHP with 3998.623ms as my longest test case.  After that, I solved "Date Battle" in 142.191ms and "Breathalyzer" in 19167.797ms. 

Finally, I spent an entire week working on "It’s a Small World" with no success.  I did everything I could. Without giving too much away, I created a balanced kd-tree and used a kNN search but it still ended up being WAY to slow.  I’ve optimized it into the ground, everything is running as fast as PHP can get away with.  Even after code profiling, I found all of my time is spent calculating SQRT (using BCMath) and I can’t figure a way to speed that up (stupid 20 decimal places).

So I’ve taken a break, hoping for that moment of enlightenment again.

2 Comments
« Older Posts


  • Donate

    If my work has helped you and you want to return the favor, you could purchase something for me from my Amazon Wish List or send me a donation via PayPal.

  • My Lifestream

  • License

    Unless otherwise noted, all source code and compiled files published on this website are released under the terms of the GNU Lesser General Public License.