You can only hash one user at a time if you operate under the constraints you've outlined.
Right. Because there's a salt, so rainbow table attacks are prevented.
Stop cherry picking your argument and address the matter at hand. Yes, brute forcing one user at a time with or without a salt would take the same amount of time. That is NOT a realistic scenario in the case of a database being compromised. Once again, you can take an outlying case and make it say anything you want. We aren't talking about tailor made cases to fit your conjecture.
You said:
Gat3way detailed it fairly well, which explains why salts (when properly implemented) offer some protection against bruteforcing and, as you correctly stated, rainbow tables. However, a properly implemented salt system increases the compute requirement for bruceforcing dramatically, slowing own the bruteforce by a factor inversely proportional to the complexity of the salt.
So you're saying that salts are helpful against attacks that do not use rainbow-table-like attacks. That is, you're saying that an attacker trying to reverse a
single hash
without looking at other hashes (a brute-force attack as opposed to a rainbow table attack) is worse off when there is a known salt present. This is false. In almost all password systems, salts are less than 32 characters, which does not make brute-forcing of a single hash any slower. If you're trying to slow down brute-forcing, you typically increase the number of hash iterations, which doesn't require you to store more data.
I am not saying that. I said NOTHING like that. In fact, I said EXACTLY THE OPPOSITE. Re-read what I wrote.
A realistic scenario is an attacker brute forcing an entire (or large subset of the entire) user table of a database. Trying to brute force a single user without knowing the strength of the underlying password is just dumb. Unless you need access to a specific user for a specific purpose, you are going to attack the whole database to get at the weakest passwords as quickly as possible.
This is where a properly implemented salt system protects you, and protects you fairly well, from a brute force attack.
Broken salt implementation with no protection:
In a static salt (or no salt) situation (both being broken implementations of a salting mechanism), the attacker has already precomputed the salt and then compares the hashes + salt. Ok, no advantage there. Duh!
1 try = 1 cycle
Properly implemented salt:
Random salt. The attacker can not pre-compute the salt, because it's different for every user.
1 cycle = gather salt into memory
1 cycle = compute salt
1 cycle = compare salt + password hash
1 try = 3 cycles. Ta-da! You've just increased the time it takes to brute force a dataset by 3x.
With some nifty coding, you might be able to combine two of those steps. You've still DOUBLED the time it takes to brute force a dataset.
I would say a 2 - 3x increase in brute force time is some hefty protection, personally. You can disagree all you want, but the fact remains that properly implementing salt is a first line defense against brute forcing and when properly implemented is going to thwart all but the most determined crackers. A static salt is fairly worthless for anything but thwarting a rainbow table, so quit holding up static salts as your pivotal argument, since that is not what we are talking about. We are talking about properly implemented salting mechanisms. Static salts are not properly implemented.
PS -
I forgot to address this:
In almost all password systems, salts are less than 32 characters, which does not make brute-forcing of a single hash any slower. If you're trying to slow down brute-forcing, you typically increase the number of hash iterations, which doesn't require you to store more data.
So again, you are holding up some sort of broken password system as an example of why password systems don't work? I don't understand your chain of logic. What properly implemented salt system would use a short salt, besides maybe crypt? But, by your logic, then a > 32 character salt would offer protection? That being the case, you've just agreed with everything I've been saying and invalidated your entire argument.