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); } }