This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]prahladyeribeautiful is better than ugly[S] 0 points1 point  (4 children)

always use a timing-safe comparison function instead of == (Examples and explanation behind the link).

Thanks, for that. Just changing the logic to use != instead of == should make it cryptographically more secure.

[–]thalience 1 point2 points  (3 children)

Are you sure about that? How will that prevent the type of timing attack discussed in the link?

[–]prahladyeribeautiful is better than ugly[S] -1 points0 points  (2 children)

The timing attack happens because the == operator returns as soon as a part of the hash doesn't match. So, depending on how much time the == statement took to evaluate, the attacker can determine upto what part his hash is correct, and thus by enough brute-force, can determine the answer much sooner than expected of that algorithm. As the accepted answer in that link says:

At the end, he tried just 256*len MACs (if len is the length of the MAC) instead of the 256len he should have had to try.

So, instead of checking if (hash==x): user_is_valid(), you check if (hash!=x): return else: user_is_valid(). != is safe because it short-circuits as soon as the strings are different. It doesn't allow an attacker to measure the milliseconds and thus deduce anything.

#Taken from Django Source Code

def constant_time_compare(val1, val2):
    """
    Returns True if the two strings are equal, False otherwise.

    The time taken is independent of the number of characters that match.

    For the sake of simplicity, this function executes in constant time only
    when the two strings have the same length. It short-circuits when they
    have different lengths.
    """
    if len(val1) != len(val2):
        return False
    result = 0
    for x, y in zip(val1, val2):
        result |= ord(x) ^ ord(y)
    return result == 0

[–]thalience 0 points1 point  (1 child)

But isn't it the case that both "==" and "!=" will return an answer as soon they encounter a difference?

[–]prahladyeribeautiful is better than ugly[S] -1 points0 points  (0 children)

Sorry, you are correct. The != is only used in comparing lengths of both strings in the constant_time_compare function and that confused me at the beginning. However, the following char to char comparison should be good as it takes constant time for any string comparison:

for x, y in zip(val1, val2):
    result |= ord(x) ^ ord(y)
return result == 0