Apr 27, 2010
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))
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).
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.
Apr 26, 2010
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.
Apr 23, 2010
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.
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!
Apr 11, 2010
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:
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.
Apr 9, 2010
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.