Search code examples
securityauthenticationpasswordsuser-experience

Why does it take so long for most applications to verify that a password is incorrect?


SSH and *NIX logins in general come to mind in particular, though I've seen this in many different apps, including Windows logins. It's seemingly much less common in web apps for some reason. Isn't the process just "hash the input password and compare it to an existing hash"? Wouldn't this cost the same regardless of whether the password is correct or not? In *NIX you can kill the login attempt no problem so its not really much of a deterrent to an attacker making repeated attempts.


Solution

  • Usually, there is an artifical random wait time if the login failed. This is to prevent timing attacks. If the password would be stored unhashed (or a weak hashing method is used) this prevents an attacker from measuring how long it took the system to compare the two password strings. Lets assume the correct password would be "abc". Now an attacker would try the passwords 'a' to 'z' repeatedly and see that for the password 'a' the time to denial the login is longer than for 'b' to 'z'. That is because the system has to compare two bytes ('a' and null-byte) to the real password to realize that 'a' is not the correct password. Then the attacker would try 'aa' to 'az', and he could realize that for 'ab' it takes the system longer to realize that the password is wrong. Using this method it is possible to massively reduce the search space and therefore decrease the time it takes to bruteforce the password. If you compensate for this by adding pseudo-random wait times after the passwords have been compared, measuring the time it took the system to compare the two passwords becomes more difficult. Even more so if the login process measures how long it took to compare the passwords and then subtract that from the random wait time, to prevent drawing information by statistical anomaly detection. Obviously, if the passwords are hashed using strong hashing methods for which no rainbow tables exist, then this becomes pointless as one cannot purposefully generate passwords with a certain hash prefix. The reason that most web apps do not employ this technique is either that HTTP and common webservers add so much noise to the processing time, that such timing attacks become infeasible or that most web devs just don't care ;)

    Additionally, this also decreases the amount of possible password attempts for an attacker, as the login has to be aborted prior to trying the next password on that connection (in the case of ssh).