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 1819
情书的邮戳
情书的邮戳 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 04:54

    This should take approximately the same time for any matching length Strings. It's constant-time with a big constant.

    public static boolean areEqualConstantTime(String a, String b) {
        if ( a.length != b.length ) {
            return false;
        }
    
        boolean equal = true;
        for ( long i = 0; i < (Long)Integer.MAX_INT; i++ ) {
            if ( a.charAt((int)(i % aChars.length)) != b.charAt((int)(i % bChars.length))) {
                equal = false;
            }
        }
        return equal;
    }
    

    Edit

    Wow, if you're just trying to avoid leaking timing information this facetious answer got pretty close to the mark! We can start with a naive approach like this:

    public static boolean arePasswordsEqual(String a, String b) {
        boolean equal = true;
        if ( a.length != b.length ) {
           equal = false;
        }
    
        for ( int i = 0; i < MAX_PASSWORD_LENGTH; i++ ) {
            if ( a.charAt(i%a.length()) != b.charAt(i%b.length()) ) {
                equal = false;
            }
        }
        return equal;
     }
    

    We need the MAX_PASSWORD_LENGTH constant because we can't simply use either the max or the min of the two input lengths as that would also leak timing information. An attacker could start with a very small guess and see how long the function takes. When the function time plateaus, he would know his password has the right length which eliminates much of the range of values he needs to try.

提交回复
热议问题