Thinktecture.IdentityModel: Comparing Strings without leaking Timinig Information

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;
    }
 
    if (s1 == null || s2 == null)
    {
        return false;
    }
 
    if (s1.Length != s2.Length)
    {
        return false;
    }
 
    var s1chars = s1.ToCharArray();
    var s2chars = s2.ToCharArray();
 
    int hits = 0;
    for (int i = 0; i < s1.Length; i++)
    {
        if (s1chars[i].Equals(s2chars[i]))
        {
            hits += 2;
        }
        else
        {
            hits += 1;
        }
    }
 
    bool same = (hits == s1.Length * 2);
 
    if (!same)
    {
        var rnd = new CryptoRandom();
        Thread.Sleep(rnd.Next(0, 10));
    }
 
    return same;
}

This entry was posted in IdentityModel. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s