private async Task <string> IsValidRequest(HttpRequestMessage request, UserApiAuthKey apiAuthKey, string incomingBase64Signature, string nonce)
        {
            if (!apiAuthKey.IsValid)
            {
                return($"Authentication key is invalid.");
            }

            if (await IsReplayRequest(apiAuthKey.Key, nonce))
            {
                return($"Nonce has already been used for this request.");
            }

            string requestHttpMethod = request.Method.Method;
            var    content           = await request.Content.ReadAsByteArrayAsync().ConfigureAwait(false);

            string requestContentBase64String       = GetMD5String(content);
            string requestContentBase64StringNonMd5 = Convert.ToBase64String(content);
            string requestUri            = HttpUtility.UrlEncode(request.RequestUri.AbsoluteUri.ToLower());
            string base64Signature       = String.Format("{0}{1}{2}{3}{4}", apiAuthKey.Key, requestHttpMethod, requestUri, nonce, requestContentBase64String);
            string base64SignatureNonMd5 = String.Format("{0}{1}{2}{3}{4}", apiAuthKey.Key, requestHttpMethod, requestUri, nonce, requestContentBase64StringNonMd5);

            if (VerifySignature(apiAuthKey, incomingBase64Signature, base64Signature) || VerifySignature(apiAuthKey, incomingBase64Signature, base64SignatureNonMd5))
            {
                return(string.Empty);
            }
            return($"Signature does not match request parameters.");
        }
        private bool VerifySignature(UserApiAuthKey apiAuthKey, string requestSignature, string serverSignature)
        {
            var secretKeyBytes = Convert.FromBase64String(apiAuthKey.Secret);

            byte[] signature = Encoding.UTF8.GetBytes(serverSignature);
            using (HMACSHA256 hmac = new HMACSHA256(secretKeyBytes))
            {
                byte[] signatureBytes = hmac.ComputeHash(signature);
                if (requestSignature.Equals(Convert.ToBase64String(signatureBytes), StringComparison.Ordinal))
                {
                    return(true);
                }
                return(false);
            }
        }