Assuming we want to protect against timing attacks on our hashed passwords because even to know the hash may give to the attacker a significative advantage then we may want to perform a constant-time or fixed-time string comparison for our hashes.
However constant-time comparison is not a simple task as we may expect because compiler may be against us and simple random delays will just stop the most naive attacker.
With all these premises we may mitigate this issue (does we need to? passwords are often stored in databases/durable medium and in any real-world system this will add noise) using this pseudo-code:
// Possibly pre-computed or cached values...
string passwordHash = "550b1f8802ca3d7a987fc46a2af408c3";
int shortPasswordHash = SimpleHash(passwordHash);
// Function to validate a password
bool IsPasswordValid(string hashedPasswordToValidate)
{
if (SimpleHash(hashedPasswordToValidate) != shortPasswordHash)
return false;
return hashedPasswordToValidate.Equals(hashedPassword);
}
Note that string comparison (on hashed password) is still vulnerable to a timing attack but chances to leak useful information to an attacker should be lower (and this algorithm is easily applicable in most languages - even those without a built-in constant-time password/hashes comparison).
Same reasoning is also applicable if we don't have an hashed password but directly plain-text (!!!) like this:
string password = "12345";
string longPasswordHash = BCrypt(password);
int shortPasswordHash = SumAllCharactersWithoutOverflow(longPasswordHash);
bool IsPasswordValid(string passwordToValidate)
{
string longHash = BCrypt(passwordToValidate);
int shortHash = SumAllCharactersWithoutOverflow(longHash);
if (shortHash != shortPasswordHash)
return false;
return longHash.Equals(longPasswordHash);
}
Do we still want/need to use a better constant-time comparison function in any real-world non-academic scenario?