Last active
April 26, 2018 10:18
-
-
Save gaevoy/ddf0478d17976cd4e492b0518dce69cd to your computer and use it in GitHub Desktop.
How to verify webhook's signature
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.IO; | |
using System.Text; | |
using Org.BouncyCastle.Crypto; | |
using Org.BouncyCastle.OpenSsl; | |
using Org.BouncyCastle.Security; | |
public static class WebhookSignature | |
{ | |
public static bool Verify(string publicKey, string payload, string signature) | |
{ | |
var key = (ICipherParameters)new PemReader(new StringReader(publicKey)).ReadObject(); | |
var buffer = Encoding.UTF8.GetBytes(payload); | |
var signer = SignerUtilities.GetSigner("SHA256withRSA"); | |
signer.Init(false, key); | |
signer.BlockUpdate(buffer, 0, buffer.Length); | |
return signer.VerifySignature(Convert.FromBase64String(signature)); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.IO; | |
using System.Net; | |
using System.Threading.Tasks; | |
using Microsoft.Owin; | |
using Org.BouncyCastle.Crypto; | |
using Org.BouncyCastle.OpenSsl; | |
using Org.BouncyCastle.Security; | |
public class WebhookVerifierMiddleware : OwinMiddleware | |
{ | |
private readonly string _url; | |
private readonly string _publicKey; | |
public WebhookVerifierMiddleware(OwinMiddleware next, string url, string publicKey) : base(next) | |
{ | |
_url = url; | |
_publicKey = publicKey; | |
} | |
public override async Task Invoke(IOwinContext ctx) | |
{ | |
var req = ctx.Request; | |
if (req.Path.Value.StartsWith(_url, StringComparison.OrdinalIgnoreCase)) | |
{ | |
var body = new MemoryStream(); | |
await req.Body.CopyToAsync(body); | |
body.Position = 0; | |
req.Body = body; | |
if (!VerifySignature(_publicKey, body.ToArray(), req.Headers["X-Signature"])) | |
{ | |
ctx.Response.StatusCode = (int)HttpStatusCode.BadRequest; | |
return; | |
} | |
} | |
await Next.Invoke(ctx); | |
} | |
private static bool VerifySignature(string publicKey, byte[] payload, string signature) | |
{ | |
try | |
{ | |
var key = (ICipherParameters)new PemReader(new StringReader(publicKey)).ReadObject(); | |
var signer = SignerUtilities.GetSigner("SHA256withRSA"); | |
signer.Init(false, key); | |
signer.BlockUpdate(payload, 0, payload.Length); | |
return signer.VerifySignature(Convert.FromBase64String(signature)); | |
} | |
catch | |
{ | |
return false; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
There are dependencies to
BouncyCastle
andMicrosoft.Owin
forWebhookVerifierMiddleware
so as prerequisite you must install:In order to enable
WebhookVerifierMiddleware
change your Owin startup code to look like: