-1

On Stackoverflow I found the following String-Equal-Function, which should be resistent against timing attacks.

private boolean equalSignatureString(String signature1, String signature2) {
    if(signature1.length() != signature2.length()) {
        return false;
    }

    byte[] signature1Byte = signature1.getBytes();
    byte[] signature2Byte = signature2.getBytes();

    int result = 0;
    for(int i = 0; i < signature1Byte.length; i++) {
        result |= signature1Byte[i] ^ signature2Byte[i];
    }
    return result == 0;
}

I wonder why this is save against timing-attacks. I understand, that we compare the complete length of the strings even if they doesn't match after the first char (which could be a point for timing attacks). But if signature1Byte[i] is not equal to signature2Byte[i] then we have to add +1 to result otherwise not. Doesn't the "add +1" takes also longer than "just proceed to the next loop"? Wouldn't it be better to count up an other variable (which is useless) when the bytes are equal, so we always have the same running time?

  • 1
    "But if signature1Byte[i] is not equal to signature2Byte[i] then we have to add +1 to result otherwise not." No, in every case it just performs a bitwise OR. I would expect that to take the same amount of time regardless of the operands. (I'm concerned about the call to `String.getBytes` without an encoding, and it's not clear why they need to be converted to byte arrays at all to be honest, but that's s different matter.) – Jon Skeet Nov 14 '18 at 08:20
  • While this is fine as an implementation, it is likely to be substantially slower and more complicated than `signature1.equals(signature2)` It's seems to assume it will almost always be a match which is why it doesn't stop as soon as it knows there is a mismatch. – Peter Lawrey Nov 14 '18 at 08:34
  • 1
    @PeterLawrey no, the .equals-Method is not protected against timing attacks, please look at other questions about this in the stackoverflow forum – lkjwedm223 Nov 14 '18 at 08:37
  • @JonSkeet mhh so I could leave the convertion to the byte-Arrays away and do it with `signature1.charAt(i)`? And what does the bitwise OR do, if `signature1[i]==signature2[i]`? Because if its not equal its add +1 to result, but what does it do, if it is true? – lkjwedm223 Nov 14 '18 at 08:38
  • There is nowhere an "add +1" in the code. What do you mean? – Henry Nov 14 '18 at 08:41
  • I would have thought storing a passwords in clear text would be more of an issue. You can use reflection to just look up the string, no need to be clever about it. The best way to prevent this and other attacks is to hash the password which has been a standard way to store such data for decades. – Peter Lawrey Nov 14 '18 at 08:42
  • @PeterLawrey if you hash an password and your equal-Method is vurlnerable against timing attacks you can theoreticly bruteforce the password in 32*32+256 trys. So the best hashing doesn't do anything if you can perform a timing attack on it... – lkjwedm223 Nov 14 '18 at 08:45
  • @Henry I mean `result |= signature1Byte[i]^signature2Byte[i]`. If this is false it does "add" +1 to result, doesn't it? (I know that this is a bitwise OR, but I still think it somehow adds +1 to result) – lkjwedm223 Nov 14 '18 at 08:47
  • The bitwise or will always take the same time, no matter what the values are. Why should `0|1` be slower than `0|0`? – Henry Nov 14 '18 at 08:48
  • Yes, for the bitwise or operator its true. I'm concerned about the `|=` operator. Doesn't this takes longer for `result |= 1` then for `result |= 0`? Or how does this operator works? – lkjwedm223 Nov 14 '18 at 08:50
  • A reasonable hash function would make randomize the change of any bit so there is no way to incrementally guess the input to the hash function. If you could do as you suggest, it would be useless for storing passwords, for the reason you point out. – Peter Lawrey Nov 14 '18 at 08:53
  • 2
    @PeterLawrey this isn't the question. I haven't specified the reason why I need a equal string function, which is protected against timing attacks. And still if you are concerned please look it up, every hash library is protected against timing attacks and thsi has a reason. Lets stop the argumentation here – lkjwedm223 Nov 14 '18 at 08:55
  • 2
    `result |= 1` is basically the same as `result = result | 1`. – Henry Nov 14 '18 at 08:58
  • Ohh okay, well that explains my concern. Than thank you very much for helping! :) – lkjwedm223 Nov 14 '18 at 09:00

1 Answers1

1

While we you could possible do that, implementation which use if not only slower, but may have unpredictable problem because of optimization.

JIT may throw away your unused variable and CPU branch prediction may also influence on how long each branch is executed.

talex
  • 17,973
  • 3
  • 29
  • 66