When it comes to security, there is a lot of dogmatic beliefs out there. For instance, some guy recommended that I hash my passwords thousands of times. This was due to that if my hashing algorithm took one second to execute, a Rainbow/Dictionary attack brute forcing my passwords, for then to perform a lookup towards the hash values of my password file, would simply not work. These are considered “best practice” in our industry, and you can find entire sections at StackOverflow.Com arguing for this approach. In fact, there are even multiple libraries written for this sole purpose.
There are two problems with that approach. Both problems arises from the fact of that Phosphorus Five is implemented in C#. This implies that what’s a “slow hashing function” in C#, can easily be “lubricated” in assembly or C to become blistering fast! The second problem is that each iteration of hashing would require some heap memory, making the garbage collector kick in every n times a user tries to login – Rendering the system for all practical concerns USELESS!
So instead of relying upon “best practices” in regards to this problem, I asked myself what IS the problem. Well, the problem is that if an adversary gains physical access to your password file for some reasons, he can gain access to your passwords. The first time we “fixed” this problem, we fixed it by hashing our passwords, for then to never store our passwords in plain text. Then some jerk came around and figured he could use a Rainbow attack to brute force your password file. This works in such a way that he generates the hash value for every possible combination of characters that could in theory be used as a password. Generating every single hash value, for every single possible combination of characters in the alphabet up to 8 characters in length, requires surprisingly small amount of time, and can actually be done in seconds, with very few resources. Then he could simply take an existing hashed password, find its instance in his “Rainbow database”, and such find your password.
So we started salting our passwords, with a “per user” salt, to make sure even if an adversary manages to crack one of the passwords in your file, he still won’t be able to do a lookup for multiple occurrences in your password file, having the same hash value. In addition, we started “slow hashing”. Slow hashing implies that we hash thousands of times, resulting in that generating the hash for a single password combination, takes at least one second. Implying that creating this “dictionary” of pre-hashed values would require too much CPU time to be of practical usage. First of all, this implies adding a LOT of CPU overhead to your application. Secondly, what is “slow” for your server, is easily within the reach of a teenager with $10,000 to rent a server farm for some few hours, and some small amounts of C/Assembly knowledge. What is slow for your server and C#, is basically peanuts for a million servers running Assembly code. An organisation such as the NSA, CIA or the FSB (**PUN!**) could eat through your “slow hashing” in milliseconds, without even noticing a “blip” on their server farm’s CPU usage …!
So you must assume that the FSB basically knows all of your password. Because this has been “industry best practices” for a decade or so, and hence “all” developers have chosen this path – Including yours … 😉
So I figured that the “best practices” in these regards were arguably broken, and effectively useless. So instead of doing a “slow hash”, I decided to rip up the problem by its roots, and instead storing the password file encrypted. Just to prove hos secure this is, I challenge my readers to figure out my password. Here is my password file …
gnupg-keypair:1EF027678DEB0FCF06266C448C4A8A3647CC8B3B Content-Type: multipart/encrypted; boundary="=-LLyo/DkZazvC4JmU6M3Qag=="; protocol="application/pgp-encrypted" --=-LLyo/DkZazvC4JmU6M3Qag== Content-Type: application/pgp-encrypted Content-Disposition: attachment Content-Transfer-Encoding: 7bit Version: 1 --=-LLyo/DkZazvC4JmU6M3Qag== Content-Type: application/octet-stream Content-Disposition: attachment -----BEGIN PGP MESSAGE----- Version: hQIMA4xKijZHzIs7AQ//U5kniwVL6jOR1onW5Itr3CZ5BvL3LykxcjMYyVC2Qdjj RZ4EWZ3W++i4CgTLynwxWz47kq20Mn9RmKbVkXqWsj51bHGAbIi/U6np/STlrWaJ /9dnDSR9UeaLmpP0h0uVmWrzCx2NmljGSY8ClrCWKN1iNhSlIDGgVNYf2mpps20l C4bqO+HYiYWWdr9uesPlk+MKJrIgKoGZq9OY3kYp2pS1+w4t2M2/rwP8sx8cWXOk TV2Bp+NQIIccGEwzRpDiTKtZANI+uQX0c7IzQEYAXm1EfKH636NlCQtGNWYR3Dex R4flBFUvzSp4eJa3/B+Y3eqs0R55wMubqSXsPzVCp5kMFTv1xSnJbsRsUoPBeNS6 1T92mlHB1Uviy5FOktNJrAuMtw5E8Z7ZD4/0sXIeplo9fKt6XoO3ou7w7CKckxoH lUIc/OBx8N0dAljYICpR4IObNPb3T3XRJ3m/+Onsf0NBJIrznLUUGtCFE/GFrMRL 4DVU9P0cAWyVAwHzZUgoejfw8g04jmIld0dLttPeq0oBZxiG5T04hBlarivl2Nb9 M31fdg8fmD2C9hDI/W68BT07SaoVkLDoUTA7c56mOtHnjLhYGqULIKpL3nCaWUg8 efj7n6P5b8eavGY+2DgGenrdblWgypk9H61iSuTcaNMk3fGkbAlKcwPXEyus2gvS tQGtb/sNVJS7PqhY3Lg28PQN2AlSw3DfUsdy4WfyRNDUgIPMHA0C22eRTsNVqyVN tzO7F/n8FkaYDH2hZstocgcMHnAxUcOzanO/DQF4m49UtfMHcb6Vhhlh2X2zDUok L8CDiVWC7XNjhjyapiJGA/I3NdMjQWwrhbdvFFH3qiuPGybMnUIjAX+kcPCGY024 ieVj67Lntuh+ILnIDqdrJPXRfAJ9xhUpBNR2/sv5AxDpFWiNm9A= =fHHa -----END PGP MESSAGE----- --=-LLyo/DkZazvC4JmU6M3Qag==--
Now try to figure out my password … 😉
This of course implies that you can literally store your password file, as I have done above, as plain text on your blog. Which of course makes it much easier to create backups of your password file, in addition to providing much better security than “slow hashing”.
Due to that “slow hashing” have been our industry’s “best practices” for a long time, an estimated guess would be that 99% of all web apps in this world have password implementations, that could easily be hacked by a teenager, with $10,000 to rent a server farm, and some above average C/ASM knowledge, in a couple of hours …
If that makes your paranoid, I happen to know the solution to your problem 😀