7

Theoretical question - Say we have a randomly generated password with 80-bit entropy, stored as a single-round, unsalted SHA256 hash. For a determined attacker with current (2024) technology, what would be the cost of bruteforcing it, in terms of money and time?

Now what if it's stored with 10 rounds of SHA256? Does that make it 10 times more resistant?

Note that I'm aware of somewhat similar questions, but they are all several years old.

user13525
  • 73
  • 1
  • 5

4 Answers4

26

A random password with 80 bits of entropy is probably out of reach of most brute-force attackers in 2024, except those that are very well funded (e.g. cybergangs, 3-letter agencies, nation states, etc).

An attacker with ~$2300 of ASIC hardware can do about 190 tera-hashes per second. So, the time it would take to iterate through 2^80 passwords, and hash each one would be:

(2^80) hashes    1 second           
              * -------------------- = 6362767471 seconds
                 190 * 10^12 hashes

That's over 200 years.

Of course, a well funded attacker could devote more resources to brute-forcing the password to reduce the amount of time it would take, but this would result in greater cost for the equipment.

But, regardless of this tradeoff of equipment cost versus time, the cost for the energy to run the equipment would probably be prohibitive for most attackers. Modern ASIC hardware like the unit linked above requires ~27.5 Joules of energy per tera-hash. Converting the Joules to kilo-watt hours, and assuming a cost of $0.12 USD per kilowatt hour - the cost for the energy to iterate through 2^80 passwords, and hash each one would be over one million dollars:

2^80 hashes  27.5 Joules       1 Kilowatt-hour     $0.12 USD      $1,108,182 USD
           * -------------- * ---------------- * -------------- = 
             10 ^ 12 hashes    3600000 Joules     Kilowatt-hour 

So, it would have to be a very valuable password to justify an attacker making this much of an investment to crack it.

mti2935
  • 23,468
  • 2
  • 53
  • 73
  • 1
    Thanks for the great answer! And to further clarify, would using 10 rounds of SHA256 make the attack 10 times more expensive? – user13525 Feb 25 '24 at 17:31
  • You're welcome, and thanks for posting an interesting question. Yes, 10 rounds of SHA256 would require 10 times the amount of hardware to crack the password in the same amount of time, and would require 10 times the amount of energy. – mti2935 Feb 25 '24 at 18:10
  • 7
    Minor nuance: unfortunately (for attackers), mining ASICs cannot be repurposed to crack general hashes - the hard-coded algorithms are more specialized, and not a direct match. All that means is that the $2300 number needs additional context - specifically, that a well-resourced attacker would need to fund the creation of such ASICs, rather than any ordinary user being able to drop $2300 today to start attacking password hashes. – Royce Williams Feb 25 '24 at 18:56
  • Good point, @RoyceWilliams. – mti2935 Feb 25 '24 at 19:19
  • 6
    Are botnets considered to be attainable only by well-funded cybergangs, TLA agencies, nation-states, etc.? If not, couldn't hashing be distributed across a botnet to significantly reduce the wall-clock duration? (And people running botnets aren't paying for energy consumption.) – jamesdlin Feb 25 '24 at 21:39
  • 6
    I'm not sure it's great question wording, but the question asks about unsalted SHA256. So in this scenario, the attacker may be able to spend the same amount of money to crack a large number of high-ish value passwords, rather than one very high value password. – James_pic Feb 26 '24 at 10:51
  • 5
    @jamesdlin yes that could be done in theory, but these botnets usually have little to no computational power (because the devices captured are not built for it) but rather their strength is the (comparatively) large internet bandwidth. Sending out DDOS packets is computationally cheap – Hobbamok Feb 26 '24 at 12:13
  • Excellent point, @James_pic. – mti2935 Feb 26 '24 at 12:20
  • 1
    @James_pic Assuming that the OP's "randomly generated" implies using a cryptographically secure random, I think there's very low risk of that, right? Salting protects you from people with the same exact password; the chance of anyone else having the same 80-bit, cryptographically-securely-randomly generated password is virtually zero. – yshavit Feb 26 '24 at 16:10
  • It's worth noting that the hypothetical in the question, of passwords hashed with a single round of a fash hash like sha256, isn't even best practice for password hashing recently. Approaches like bcrypt or pbkdf2 (which themselves aren't particularly new) have for years made hashing a more work-intensive process all but taking brute-forcing by hash generation off the table completely and changing the answer to this question significantly. – thomasrutter Feb 27 '24 at 00:22
  • 1
    @yshavit Salting also prevents you cracking many passwords in parallel. If passwords are unsalted, you can brute force a large collection of passwords in about the same amount time as brute forcing a single password. With salted passwords, you can only brute force one password at once, or at least only brute force passwords with the same salt at the same time. – James_pic Feb 27 '24 at 09:41
  • 1
    @James_pic exactly. So if the attacker obtains a million unsalted hashes, he can crack them for the same cost as a single unsalted hash. - So if a lot of people use this method to e.g. secure their crypto-wallet even the Million Dollars of Energy could become profitable if the attacker could for example acquire crypto-currency worth hundreds of millions with the mass of cracked passwords. – Falco Feb 27 '24 at 12:52
  • @James_pic Oh, I think I see — is the idea that rather than spitting out guesses for a given hash-to-crack, you just spit out guesses of hashes and see which hashes-to-crack match? – yshavit Feb 27 '24 at 16:09
  • @user13525. Assuming that the attacker knows that you used 10 rouunds of sha256? nope.

    Because there exists a function that creates the output of 10 rounds of sha 256, using a single round.

    – Questor Feb 27 '24 at 19:54
  • So an attacker with 2.3 million dollars can crack it in 0.2 years; with not much additional effort, they can also generate a rainbow table that can crack any unsalted password following this specification. – user253751 Feb 28 '24 at 17:02
8

If you’re brute forcing it without a database breach then the time depends on how often the front end lets you make a login attempt. A well-designed system will in any case lock the account after let’s say ten consecutive failed logins, and in that scenario your brute force will almost certainly fail. If you do have a database breach then of course no brute force is needed — you’ve got the password, since you specified it was stored as plaintext.

Mike Scott
  • 10,294
  • 1
  • 29
  • 36
  • 1
    You're right, if it's stored as plaintext the question is not very interesting - I've changed the scenario to "stored as a single-round, unsalted SHA256 hash". – user13525 Feb 25 '24 at 08:36
  • This answer still holds true. Because usually you obtain the password by accessing the database. In many scenarios you will not have to crack the password, if you have access to the database. Either you already have all the information you need from the database, or the hash of the password is enough to login into the application (e.g. the password is hashed in the browser to login and the hash is compared to the saved hash) – Falco Feb 27 '24 at 12:56
  • 3
    @Falco: Directly storing the thing the client needs to send over the wire is an obvious design error. If you want to make sure the server never sees actual human-readable ASCII text versions of passwords, send a hash, but then have the password table on the server store a hash of that hash, right? So sha256("password") is the plaintext password as far as the server is concerned, and bcrypt or sha256 of that is the hashed password. (I don't doubt that many systems have the bad design you're talking about, though, in which case a user choosing a password can't do anything about it.) – Peter Cordes Feb 27 '24 at 21:09
  • 1
    @PeterCordes I would not call it an "obvious" design error. There are several performance and compatibility benefits and the plain-text password never leaves the clients PC. There is of course the depicted vulnerability that an attacker with access to the best protected parts of your database can impersonate the user to your application. But arguably this attacker already has the keys to the kingdom anyways. - So there remains the defense-in-depth argument. – Falco Mar 04 '24 at 10:23
  • @PeterCordes An example where such a design might be chosen is an app with a very high number of daily logins to access data. The computation cycles for hashing passwords on the server might be a relevant cost factor, while the attack surface is only access to the protected data, which an attacker with access to the database has anyways. – Falco Mar 04 '24 at 10:26
6

First the simple part

A lot of specialized high-performance computing resources worldwide are used for Bitcoin mining. All together they compute about 650 EH/s (different resources like ycharts or coinwarz give similar values), which is about 269/s. To brute-force an 80-bit secret they would need 280-69s = 211s = 2048s ~= 34min.

These computations consume about 4.5MWh/s (e.g. look at digiconomist: 142TWh/year ~= 4.5MWh/s). This means, that to brute-force an 80-bit secret, one would need about 9.2GWh energy. Using very cheap prices of 0.05 USD/KWh like in Saudi Arabia or Nigeria would cost about 460 000 USD. In reality, with a prices mix (see statista) it may cost even more, like 1 000 000 USD. But you would also need to pay for hardware, cooling, and personnel.

Now you can decide if there is anyone in the World who is willing to pay at least 1 000 000 USD for brute-forcing.

You don't use salt. This can make brute-forcing easier. Suppose you add salt.

Then 1 000 000 USD will be the price of a single password For every further password one would have to pay this amount of money again.

But...

These calculations may give a false feeling of security, if you don't tell us what attack vectors and risks you consider.

In reality, an attack may be much cheaper:

  • If the application writes passwords to the log...
  • If you keep plain passwords in memory for a relatively long time and the attacker can make memory dumps...
  • If the attacker gets access to the private TLS key...
  • If the network between the TLS termination point and the application is not trusted and you don't use encryption...
  • If users don't keep their passwords properly...
mentallurg
  • 12,418
  • 5
  • 36
  • 50
  • 8
    Obligatory xkcd. – Ralph J Feb 25 '24 at 21:27
  • 1
    @RalphJ: To "Obligatory xkcd" - Your example is irrelevant. See the OP. It clearly says it is about 80-bits random password. – mentallurg Feb 25 '24 at 22:03
  • 5
    The xkcd is an example of how "an attack can be much cheaper..." i.e. your final paragraph. Along with users not keeping their passwords properly and the other ways to defeat a password that's too expensive to crack, the scenario envisioned there applies. The energy costs are $1.1M in the other post, and $643M in your comment, or $1B in your post. That's a big gap for estimations & 37% slower devices. – Ralph J Feb 26 '24 at 00:55
  • It's unsalted, so 1 million USD makes a rainbow table that will crack all similar passwords. – user253751 Feb 28 '24 at 17:07
  • @user253751: Wrong. The idea is good, but first tell us how much memory you have to store it – mentallurg Feb 28 '24 at 19:02
5

Addressing specifically the question about repeated hashing:

Yes, hashing the password repeatedly (i.e. storing H(H(...(H(password))...))) will make the attack proportionally more expensive. The process of taking a password and processing it with expensive computation, to make it harder to crack is called "stretching". In modern systems, stored passwords are always stretched, and doing only 10 rounds of hashing would be unusually weak. (Stored passwords are also always salted, but this doesn't impact the difficulty of a targeted attack against a specific password; only the difficulty of less-targeted attacks.)

There is a standard for password stretching by repeated hashing, PBKDF2. It also does some other stuff that doesn't impact the computational cost of the hashing. Originally, the minimum recommended number of hashing iterations for PBKDF2 was 1000... almost 25 years ago. A modern recommendation is something like a million iterations.

More commonly these days, a different function would be used entirely, such as bcrypt or argon2. Whereas repeated hashing just uses as much CPU as possible, bcrypt and argon2 also require significant amounts of memory. Functions that use a lot of memory aim to favor CPUs (which the defenders are using) over GPUs or more special purpose hardware that an attacker might have.

All of this should be taken as general background on the topic of password storage only. There's a lot more you should know before trying to build a password storage or authentication system.

Glenn Willen
  • 150
  • 4
  • 2
    Hashing that many times is not good. Adding passes gives a linear benefit (10 passes takes 10x as long to crack as 1 pass) but using a longer salt/key length offers exponentially better protection (10 bits takes 1024x as long to crack as 1 bit). The reason older encryption methods recommended 1000+ passes was because the algorithms were not completely random; so, lots of passes helped hide the vulnerability of poor randomness. Modern methods are much more random and typically recommend 12-64 passes. In fact, too many passes can create patterns in you encryption making it easier to crack. – Nosajimiki Feb 27 '24 at 17:00
  • @Nosajimiki Can you provide some reference for what you're referring to? It goes against everything I understand to be best practice; also, you mention "encryption", but there is typically no encryption involved in the process of password storage. (The length of the salt is irrelevant to the situation where the password database containing the salts is leaked, which is typical. Obviously the length of the input to the hash is more important than the number of rounds, as you say; but the input is the user's password, and there are obvious issues with making it extremely long.) – Glenn Willen Feb 28 '24 at 00:12
  • Wew... so this is a lot to cover in comments, but I'll try to keep it brief. Hashing (1-way encryption) is a type of encryption even though we often just say encryption when specifically meaning 2-way encryption. In this case, I am talking about all kinds of encryption. As for number of passes: no encryption method is 100% random, but each method is used to reach a peak distribution of values within a recommended number of passes. – Nosajimiki Feb 28 '24 at 15:22
  • When you do too many passes, patterns can become more obvious, like if every 5th character is slightly more likely to be a 2, then after a million passes, the 5th character may typically be a 2. Modern hackers using AIs ( which are especially good a pattern recognition) can make inferences from large enough of a set of Hashed passwords to build heuristics about your encryption method. These heuristics are then used to prioritize what kinds of solutions that are more likely than others which can speed up a brute force attack by a significant margin. – Nosajimiki Feb 28 '24 at 15:23
  • 1
    By keeping your number of passes close to the suggested number, you make heuristics modeling far more difficult. As for salt length, there are lots of ways to do salts that add security to a hash in different ways. The best salts are 2-part salts. 1 part is kept is a static key kept somewhere in a config file outside of your database, that way, if they get a SQL dump, they don't get the static salt too. So, if your static salt is '7dj3Hf' and your password is 'Qw3rty!', – Nosajimiki Feb 28 '24 at 15:23
  • then your password goes from 7 unknown characters to 13 unknown characters. The second part of your salt should be a random string generated for a specific password to make sure that each hash is unique, even if a password is reused. So, if your dynamic salt if '4bsdJ2' then your whole password that you hash becomes '7dj3Hf4bsdJ2Qw3rty!' which is a lot more random than a shorter salt, even if part of the salt is known. – Nosajimiki Feb 28 '24 at 15:23
  • 1
  • The OP does not use salt. 2) The purpose of salt is to prevent usage of rainbow tables. It does not need to be secret. The only requirement - it should not be reused, or reused as little as possible. 3) In case of password hashing salt should be not secret, otherwise there will be no way to compute the hash to check the password.
  • – mentallurg Feb 28 '24 at 19:09