John Deters's answer explains why using more digits for 2FA codes is a good thing, but he hasn't shown the math. Moreover, he invites readers to check his calculations, and I think there are some errors. I wanted to make an edit, but I've realised it would be way too long. So I'm posting this as a separate answer; if there is consensus that my calculations are right, we can edit his answer (or he can do it himself).
The goal is to calculate how many attempts an attacker needs to guess a 2FA code of a given length. The attacker succeeds if, making several attempts, he can guess at least one. "At least 1" is hard to calculate directly, so let's use a trick:
P(at least one code is guessed) = 1 - P(no codes are guessed)
Now, from the binomial formula, the probability of getting exactly k=0
successes in n
trials is simply
(1-p)^n
so
P(at least one code is guessed) = 1 - (1-p)^n
So, for a given p=3/1000
(3 attempts before the account is locked, where the total possible 3-digit codes are 1000), what's the number of attempts n
that an attacker needs to have a probability of success greater than 50%?
P(at least one code is guessed) > 50%
1 - (1-p)^n > 50%
(1-p)^n < (1 - 50%)
(I'm leaving it as 1 - 50%
, instead of replacing it with the result 1/2, because at the end we'll repeat the calculation to have a probability of 99%, and in that case I want it to be clear that we don't have to write 0.99, but rather 0.01. I could have left a variable there, like desired_success_probability, but I thought it would be less readable)
Now, to extract n
, let's take the logarithm to base (1-p) of both members. Since the base is less than 1, and the logarithmic function to a base less than 1 is monotonically decreasing, we have to invert the inequality, so we get:
n > log(1-p)(1 - 50%)
and by changing the base to a convenient one (for example 10 or e
-
anything goes, as long as the calculator supports it) we have the solution:
n > log(1-50%) / log(1-p)
which for p=3/1000 is
n > 230.7, that is, n >= 231.
So if the probability of guessing one code is 3/1000, after making three attempts each for 231 accounts we have that guessing at least one is more likely than guessing none.
If, instead of having a probability of success of 50%, the attacker wants to reach 99%, he needs
n > log(1-99%) / log(1-p)
which means
n > 1532.75, that is, n >= 1533
What happens if the 2FA code is, instead, 6 digits long? The probability of success for a single attempt becomes p = 3/1,000,000
, which means that the attacker needs at least 231,049 accounts to have a 50% chance of success. If he wants to have a 99% chance of success, he needs 1,535,055 accounts.
In short, by adding 3 digits we are increasing the number of possible codes by a factor of 1000, and to keep the same probability of success the attacker needs to make slightly more than 1000 times as many attempts. If these are online banking accounts, is it worth it to spend 1-2 seconds more to enter the code in order to make a thief's life 1000 times harder? In my opinion, absolutely.