How do I implement a string comparison in Java that takes the same amount of time no matter whether they match or where a mismatch (if any) occurs?

后端 未结 6 1825
情书的邮戳
情书的邮戳 2020-12-11 04:30

I want to implement a String comparison function that doesn\'t take a different amount of time depending on the number of characters that match or the position

6条回答
  •  半阙折子戏
    2020-12-11 05:10

    The following code is one common way to do a constant-time byte[] comparison in Java and avoid leaking password info via the time taken:

    public static boolean isEqual(byte[] a, byte[] b) {
        if (a.length != b.length) {
            return false;
        }
    
        int result = 0;
        for (int i = 0; i < a.length; i++) {
          result |= a[i] ^ b[i];
        }
        return result == 0;
    }
    

    See http://codahale.com/a-lesson-in-timing-attacks/ for more discussion of this issue.

    (This assumes that the length of the secret is not sensitive, for example if it is a hash. You should pad both sides to the same length if that is not true.)

    This is essentially the same as your first suggestion:

    So far, the best idea I've got is to sum the XOR of each character and return whether or not the sum is 0.

    You asked:

    However, I'm pretty sure this wouldn't work so well with Unicode.

    This is a valid concern, but you need to clarify what you will accept as "equal" for a solution to be proposed. Luckily, you also say "This would be used to compare hashed password values", so I don't think that any of the unicode concerns will be in play.

    I also have a vague concern that HotSpot would do some optimizations that would change my constant-time property,

    Hopefully that's not true. I expect that the literature on how to avoid timing attacks in Java would address this if it were true, but I can't offer you any citations to back this up :-)

提交回复
热议问题