Thinktecture.IdentityModel: Comparing Strings without leaking Timinig Information
Posted
by Your DisplayName here!
on Least Privilege
See other posts from Least Privilege
or by Your DisplayName here!
Published on Sat, 08 May 2010 19:51:07 GMT
Indexed on
2010/12/06
17:00 UTC
Read the original article
Hit count: 516
IdentityModel
Paul Hill commented on a recent post where I was comparing HMACSHA256 signatures. In a nutshell his complaint was that I am leaking timing information while doing so – or in other words, my code returned faster with wrong (or partially wrong) signatures than with the correct signature. This can be potentially used for timing attacks like this one.
I think he got a point here, especially in the era of cloud computing where you can potentially run attack code on the same physical machine as your target to do high resolution timing analysis (see here for an example).
It turns out that it is not that easy to write a time-constant string comparer due to all sort of (unexpected) clever optimization mechanisms in the CLR. With the help and feedback of Paul and Shawn I came up with this:
- Structure the code in a way that the CLR will not try to optimize it
- In addition turn off optimization (just in case a future version will come up with new optimization methods)
- Add a random sleep when the comparison fails (using Shawn’s and Stephen’s nice Random wrapper for RNGCryptoServiceProvider).
You can find the full code in the Thinktecture.IdentityModel download.
[MethodImpl(MethodImplOptions.NoOptimization)]
public static bool IsEqual(string s1, string s2)
{
if (s1
== null && s2 == null)
{
return true;
}
{
return false;
}
{
return false;
}
var s2chars
= s2.ToCharArray();
for (int i
= 0; i < s1.Length; i++)
{
if (s1chars[i].Equals(s2chars[i]))
{
hits
+= 2;
}
else
{
hits
+= 1;
}
}
{
var rnd
= new CryptoRandom();
Thread.Sleep(rnd.Next(0,
10));
}
}
© Least Privilege or respective owner