0

From the Moralis Streams API (i.e. an incoming webhook request), how do I verify the x-signature header? The docs say its just a sha3 of the body + api key, however this does not seem to work correctly. Here is what I've got so far. (part of one of my API controllers)

var signature = Request.Headers["x-signature"].FirstOrDefault(); if (signature.IsNullOrEmpty()) { logger.LogInformation("No signature was present from webhook request, ignoring."); return Ok(); } Request.EnableBuffering(); // Required to allow multiple reads // Read body again to a string using var reader = new StreamReader( Request.Body, Encoding.UTF8, detectEncodingFromByteOrderMarks: false, leaveOpen: true ); var rawBody = await reader.ReadToEndAsync(); Request.Body.Position = 0; // Hash body using var hashMemStream = new MemoryStream(); var hashMemWriter = new StreamWriter(hashMemStream); await hashMemWriter.WriteAsync(rawBody + "<streams secret here>"); await hashMemWriter.FlushAsync(); hashMemStream.Position = 0; var hash = await SHA3_256.HashDataAsync(hashMemStream); var hashString = BytesToHex(hash); Request.Body.Position = 0; if (signature != hashString) { logger.LogInformation("Signature was incorrect from webhook, ignoring"); return Ok(); } 

The BytesToHex(string) method is implemented as:

private static string BytesToHex(byte[] bytes) { var sb = new StringBuilder("0x"); foreach (var b in bytes) sb.Append($"{b:x2}"); return sb.ToString(); } 

The x-signature is the same length as what I end up with but they are not the same.

I was able to snuff out from the official JS SDK that its calculated in their SDK as:

const generatedSignature = sha3(JSON.stringify(body) + secret); (taken from https://github.com/MoralisWeb3/Moralis-JS-SDK/blob/main/packages/streams/src/methods/verifySignature.ts#L12)

It seems very odd to re-serialize the body to a JS-specific implementation to then hash. Is there a reason for this?

Whats the recommended approach to this?

1 Answer 1

0

I was able to calculate the same hash using the rawBody using Nethereum's Sha3Keccack. The Sha3 function used by web3 (and thus Moralis) is Keccack256, not the same SHA3 used by .NET's System.Security.Cryptography. The implementation looks like:

var hashString = Sha3Keccack.Current.CalculateHash(rawBody + "<streams secret>"); 
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.