If the data against which you are comparing is not a secret, then it doesn't really matter what you do. Timing attacks are used to learn information to which you do not already have access. If you already have access, then the attack is unnecessary.
If you are protecting a secret, then it doesn't matter if it is a password or not. You should handle it the same way, with the same precautions. In order to avoid timing side channels, you ensure that the input length will be the same as the stored value's length by hashing them both and doing a constant time comparison. Of course, you should store the hashed value of the stored value in the database, so that you aren't recomputing it every time. See pseudocode below.
Pseudocode for constant time comparisons:
bool compareToSecret(input/* input from user*/)
dbHash = getSecretFromDb()
inHash = hash(input); // sha256, bcrypt or whatever. Attacker
// knows how long this takes, but it
// doesn't get her anything
// at this point, both inhash and dbhash are the same length.
// the following loop is constant order time. Hashes are always the
// same length, and all values of the hashes are always compared
bool result = true
int len = strlen(inHash)
for( int i=0; i<len; i++ )
result &= (inHash[i] == dbHash[i])
return result
aborting early during comparison
Aborting early during the comparison is problematic, as it leaks info about the comparison and can be used to learn the password directly.
- Attacker tries secrets of length 1. One of these secrets will take a few milliseconds longer to return than the others, since there is one 1-length secret whose first character matches the stored secret. Attacker learns the first character of the secret.
- Attacker tries 2 all character secrets with first letter beginning with known correct value. One of these secrets will be a few milliseconds faster, since the second character compares correctly.
- Attacker repeats, separately attacking each character of the secret. Eventually, the attacker learns the stored secret.
This is quicker than a brute force attack, because the attacker can attack each character separately instead of the whole secret at once.
aborting early: before comparing
Aborting early, as mentioned by Steven Tousset, leaks the length of the secret. This doesn't look like a lot at first, but it lets the attacker speed up their attack by orders of magnitude. Let's say that the system accepts secrets of length 1-5. Keeping it very simple, the secret is composed only of digits. Thus, there are 10+100+1,000+10,000+100,000=111,110 possible values. A brute force attack needs to make about 100,000 tests to try every possible value.
If the system lets the attacker know the length of the secret, an attacker can dramatically reduce the number of values that s/he needs to test by first trying 5 values: '1', '12', '123', '1234', and '12345'. Now the attacker knows how long the secret is. If it's 1 character, s/he now only needs to make 10 tests instead of a hundred thousand. If it's 2 characters long, she only needs to make 100 tests. Without this key piece of information the attacker needs to make a lot more tests before they will find the secret.
another issue: recoverable storage
There's another issue, too. If the known secret can be compared against the input value, then you have to store the secret in recoverable form. Search this site for details related to passwords, but this is often considered a bad practice with storing passwords and should be avoided. In general - with any kind of secret - if you don't absolutely have to have the raw value, it should not be stored in recoverable form. Irrecoverable storage prevents several attacks - whether they matter for your secret depends upon how you use it.
one more thing: compiler optimization
The code, below, is pseudo code. If you were to pass its equvalent through a compiler or a runtime that does optimization, then you need to be very careful to ensure that the code does not get optimized. There are various tricks fir different languages, which are out of scope of this comment. Tha ks to @Polynomial for reminding of this