How long to brute force a salted SHA-512 hash? (salt provided)

Here is an algorithm in Java:

public String getHash(String password, String salt) throws Exception {
    String input = password + salt;
    MessageDigest md = MessageDigest.getInstance(SHA-512);
    byte[] out = md.digest(input.getBytes());
    return HexEncoder.toHex(out);

Assume the salt is known. I want to know the time to brute force for when the password is a dictionary word and also when it is not a dictionary word.


In your case, breaking the hash algorithm is equivalent to finding a collision in the hash algorithm. That means you don’t need to find the password itself (which would be a preimage attack), you just need to find an output of the hash function that is equal to the hash of a valid password (thus “collision”). Finding a collision using a birthday attack takes O(2^(n/2)) time, where n is the output length of the hash function in bits.

SHA-2 has an output size of 512 bits, so finding a collision would take O(2^256) time. Given there are no clever attacks on the algorithm itself (currently none are known for the SHA-2 hash family) this is what it takes to break the algorithm.

To get a feeling for what 2^256 actually means: currently it is believed that the number of atoms in the (entire!!!) universe is roughly 10^80 which is roughly 2^266. Assuming 32 byte input (which is reasonable for your case – 20 bytes salt + 12 bytes password) my machine takes ~0,22s (~2^-2s) for 65536 (=2^16) computations. So 2^256 computations would be done in 2^240 * 2^16 computations which would take

2^240 * 2^-2 = 2^238 ~ 10^72s ~ 3,17 * 10^64 years

Even calling this millions of years is ridiculous. And it doesn’t get much better with the fastest hardware on the planet computing thousands of hashes in parallel. No human technology will be able to crunch this number into something acceptable.

So forget brute-forcing SHA-256 here. Your next question was about dictionary words. To retrieve such weak passwords rainbow tables were used traditionally. A rainbow table is generally just a table of precomputed hash values, the idea is if you were able to precompute and store every possible hash along with its input, then it would take you O(1) to look up a given hash and retrieve a valid preimage for it. Of course this is not possible in practice since there’s no storage device that could store such enormous amounts of data. This dilemma is known as memory-time tradeoff. As you are only able to store so many values typical rainbow tables include some form of hash chaining with intermediary reduction functions (this is explained in detail in the Wikipedia article) to save on space by giving up a bit of savings in time.

Salts were a countermeasure to make such rainbow tables infeasible. To discourage attackers from precomputing a table for a specific salt it is recommended to apply per-user salt values. However, since users do not use secure, completely random passwords, it is still surprising how successful you can get if the salt is known and you just iterate over a large dictionary of common passwords in a simple trial and error scheme. The relationship between natural language and randomness is expressed as entropy. Typical password choices are generally of low entropy, whereas completely random values would contain a maximum of entropy.

The low entropy of typical passwords makes it possible that there is a relatively high chance of one of your users using a password from a relatively small database of common passwords. If you google for them, you will end up finding torrent links for such password databases, often in the gigabyte size category. Being successful with such a tool is usually in the range of minutes to days if the attacker is not restricted in any way.

That’s why generally hashing and salting alone is not enough, you need to install other safety mechanisms as well. You should use an artificially slowed down entropy-enducing method such as PBKDF2 described in PKCS#5 and you should enforce a waiting period for a given user before they may retry entering their password. A good scheme is to start with 0.5s and then doubling that time for each failed attempt. In most cases users don’t notice this and don’t fail much more often than three times on average. But it will significantly slow down any malicious outsider trying to attack your application.

Source : Link , Question Author : timothyjc , Answer Author : Marco Bonelli

Leave a Comment