I've tried to reproduce a string comparison timing oracle in two languages (Java and Python), but I'm not seeing any correlation in the timing based on the input into the comparison. Are there any examples out there, or do you see an issue with my code? Note that I would like something simple, like the example I have given. An attack on a large program "in the wild" is not a good example.
I've also not been able to find any simple and ready-to-run examples of timing attacks. I believe I've disabled Java's optimization with -Djava.compiler=NONE. It's taking a significant amount of time to run the code, so it's clearly not completely optimizing the code.
It seems odd that this is frequently talked about, but there are no actual easily-found examples out there.
Here is my Java code as it stands today. The output varies a bit randomly with no apparently correlation that I have identified. I've added some notes to the output so you can see which should be slower comparisons.
public class TimingAttackJavaTest {
public static void main(String[] args) {
TimeCompare("a0", "b0", "a, b ");
TimeCompare("aaaaaaaaaa1", "bbbbbbbbbbb1", "a*10, b*10");
TimeCompare("aaaaaaaaaa10", "bbbbbbbbbbb10", "a*10, b*10");
TimeCompare("aaaaaaaaaa2", "b2", "a*10, b ");
TimeCompare("a3", "bbbbbbbbbbb3", "a, b*10 ");
TimeCompare("aaaaaaaaaa4", "bbbbbbbbbbb4", "a*10, b*10 ");
TimeCompare("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa1", "a*100, a*100");
TimeCompare("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa1", "a*100, a*100");
TimeCompare("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa2", "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", "a*100, b*100");
TimeCompare("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa2", "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", "a*100, b*100");
TimeCompare("a", "a", "a, a ");
TimeCompare("aaaaaaaaaaa", "aaaaaaaaaaa", "a*1, a*10 ");
TimeCompare("1aaaaaaaaaa10", "2bbbbbbbbbbb10", "a*10, b*10");
}
static void TimeCompare(String a, String b, String outputLabel)
{
boolean temp = false;
long startTime;
long endTime;
long duration;
startTime = System.nanoTime();
for(int i = 0; i < 10000000; i++)
{
temp = a.equals(b);
}
endTime = System.nanoTime();
duration = endTime - startTime;
System.out.println(outputLabel + temp + "\t\t" + duration);
}
}
Output (note that the first comparison is always slow, as the program gets started):
a, b false 930418800
a*10, b*10false 513034800
a*10, b*10false 510905300
a*10, b false 534267200
a, b*10 false 524720700
a*10, b*10 false 509250100
a*100, a*100false 516159000 **This should return slowly**
a*100, a*100false 508714700 **This should return slowly**
a*100, b*100false 511160700 **This should return quickly**
a*100, b*100false 522029800 **This should return quickly**
a, a true 278492700
a*1, a*10 true 284238900
a*10, b*10false 506245000