Java: Почему эта функция Equal-String защищена от временных атак
В Stackru я обнаружил следующую String-Equal-Function, которая должна быть устойчивой к временным атакам.
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;
}
Интересно, почему это спасает от временных атак? Я понимаю, что мы сравниваем полную длину строк, даже если они не совпадают после первого символа (что может быть точкой для временных атак). Но если signature1Byte[i]
не равно signature2Byte[i]
тогда мы должны добавить +1 к result
в противном случае нет. Разве "добавить +1" также не займет больше времени, чем "просто перейти к следующему циклу"? Не лучше ли подсчитать другую переменную (которая бесполезна), когда байты равны, поэтому у нас всегда одинаковое время выполнения?
1 ответ
Хотя мы могли бы сделать это, реализация которых использует if
не только медленнее, но может иметь непредсказуемую проблему из-за оптимизации.
JIT может отбросить вашу неиспользованную переменную, и предсказание ветвления ЦП также может влиять на продолжительность выполнения каждой ветки.