[WIP] Smoking Hashes 101
In English: [Work-In-Progress] [Tutorial] Hashes
Well it's been two years since I have been on this site, so I think it's time to start off with a tutorial.
So a hash is the result of a cryptographic hashing (usually one-way encryption) function which runs an algorithm which usually returns a(n) (or multiple) unique hash(es) for every string [to a certain extent].
So what are hashes used for, you may ask?
Well, they are used for data verification, where the data is hashed and compared to a precomputed hash of the expected data, the biggest aspect of data verification is password verification. Many, not if, all sites use hashes to verify passwords, this is much more secure as hashes can not be decrypted.
So what are some examples of hashes?
Just to name to name the two most widely known/popular, MD5 and SHA1, although there are much more secure hashes. You may not have heard of this one, but it is still used more than many other hashes, what I'm talking about is phpass. It is used in phpBB3, Drupal, Wordpress and many more web applications. One of the best features of it, is what I like to call polymorphic hashes, this is when a string put through a certain function will return different hashes although they will still be able to be verified against the original string.
So why don't people just bruteforce these hashes?
Well, to put it simply it's too hard. Modern/current computers simply don't have the computing power to do this. So to calculate how long it would take your computer to generate all hashes for a certain hashing algorithm/function, you have to look at its entropy. To put it simply, the entropy is the amount of different possibilities. So MD5, which has now classified as being cryptographically broken, which I'll go into detail later, has a theoretical entropy of 2^128 because there are 128 bits in a MD5 hash (a bit can either be 0 or 1). So, you need to calculate how many times you can run the algorithm in a certain amount of time and apply that ratio to 2^128, so if my computer could theoretically calculate 2^20 MD5 hashes/second (~1 million) that would mean it'd take 2^108 seconds to compute all possibilities which is over 10290415831380857647867707 years. So bruteforcing won't really help us here if it is a long enough password, but knowing password and their inability to remember long passwords and preference to reuse this means that passwords are usually really short so instead of bruteforcing hashes they use a dictionary attack which I will also go into more detail later.
So why don't people just make massive tables of hashes as they [usually] always return the same hash?
Well, they do. These tables are called rainbow tables, which are essentially just tables with a string and a corresponding hashes. The only problem with this is that there are too many hashes that could be generated (as shown above with the example of MD5). With more secure hashes, the entropy grows which exponentially which makes it even harder to generate a complete table. Another way to secure your passwords is to add a salt which is essentially just some extra data which is added to the input, this means that the input (password with the salt included) is less likely to be found in rainbow tables and harder to bruteforce. For example if we were to hash passsword with MD5 we would obtain the hash 86a65acd94b33daa87c1c6a2d1408593. Even just searching this hash in Google will obtain you the original input being passsword. Now if we were to add a salt to the beginning like awesomesalt, so that we were now hashing awesomesaltpasssword we would obtain the hash 89502f288c9e12d2cb735106bcae0918 and just searching this in Google, unlike last time, we found no results.
If MD5 is cryptographically broken, then why can't I find the original string for any MD5 hash?
Well, because cryptographically broken doesn't mean that there's a way to instantly find the original string of any hash. It usually just means there are ways to find the original string faster than bruteforcing due to problems in the algorithm.
Okay, great, so how do I use hashing functions/algorithms?
Well, in PHP there are a lot of native hashing functions/algorithms included (although previously mentioned phpass isn't). If you would like to use MD5 or SHA1, which you shouldn't you can use their native functions
But if you want to use more cryptographically secure hashing algorithms you need to use the hash function:
That example has SHA256 being the algorithm and test being the input. Hash supports over 40 different hashing algorithms, so it is a great function to have in your arsenal. Checking my 5.3.8 using the hash_algos() to list the supported hashes within the hash function. It returned to me 42 different supported hashing algorithms. Here is what a hash from each of those 42 (there may be more on the newer versions of PHP) looks like:
Usually longer hashes are more secure.
You told me about salts before, how do I use them?
Well all you really need to do is concatenate the salt to the input string. For example:
$salt = 'aXyd54'; $string = 'test'; // FROM: hash('sha256', $string); // TO THIS: hash('sha256', $salt . $string); // OR THIS: hash('sha256', $string . $salt); // OR EVEN: hash('sha256', $salt . $string . $salt);
As long as the hackers don't know your salt or the way you add the salt, it makes it quite hard for them to bruteforce your hashes.
Thanks for reading,