private bool VerifySignature(User user, string querystring)
{
// Check that we have enough characters to avoid an ArgumentOutOfRangeException.
// If we don't have at least this many, there's certainly no hash anyway.
if (querystring.Length < 38) return false;
// All this does the same job as the following on the client side:
// var tohash = (++AjaxLife.SignedCallCount).toString() + querystring + AjaxLife.Signature;
// var hash = md5(tohash);
// First we have to remove the hash from the incoming string. We may assume the has is always at the end.
// This makes the job easy - we just chop the end off. No parsing required.
// MD5s are 128 bits, or 32 hex characters, so we chop off "&hash=00000000000000000000000000000000", which is
// 38 characters.
string receivedhash = querystring.Substring(querystring.Length - 32); // Grab the last 32 characters.
querystring = querystring.Remove(querystring.Length - 38); // Strip the hash off.
++user.SignedCallCount; // Increment the call count to ensure the same hash can't be used multiple times.
string tohash = user.SignedCallCount.ToString() + querystring + user.Signature; // Build the to hash string.
string expectedhash = BitConverter.ToString(md5.ComputeHash(UTF8Encoding.UTF8.GetBytes(tohash))).Replace("-", "").ToLower(); // Actually hash it.
AjaxLife.Debug("SendMessage", "VerifySignature: Received hash " + receivedhash + ", expected " + expectedhash + " (based on '" + tohash + "')");
// Check if they're equal.
return (receivedhash == expectedhash);
}