title: verify webhook post signatures from Transnational webhook
body: <p>I trying to verify webhook post signatures from Transnational payments. there documentation for this is;</p>
  <pre><code>Webhook post requests are sent with a header &quot;Signature&quot; that is HMAC SHA 256 signed and then base64 url encoded.
  
  To verify webhook post signatures, retrieve &quot;Signature&quot; from header. Base64 url decode and use HMAC SHA 256 to check using your signature UUID located in the control panel under the webhook previously created
  </code></pre>
  <p>First, when i try to Base64 Url decode the signature I get an error. here is an example of a Signature. &quot;RwtK6Kr4NOOFs9mjYPpEJWxSJQr23k6uXDktj4QEjGk&quot;</p>
  <p>THere is the example code they use to test signature comparison: , I think it's in Go.</p>
  <pre><code>sig := r.Header.Get(&quot;Signature&quot;)
  // Get the body
  body, _ := ioutil.ReadAll(r.Body)
  r.Body.Close()
  // Verify Sig
  mac := hmac.New(sha256.New, []byte(&quot;signature-to-check-here&quot;))
  mac.Write(body)
  sigCheck, _ := base64.RawURLEncoding.DecodeString(sig)
  doesitequal := hmac.Equal(sigCheck, mac.Sum(nil))
  ctx.Log().Infof(&quot;%v&quot;, doesitequal)
  </code></pre>
  <p>They also sent the code they use to encode the signature.</p>
  <pre><code>// Set webhook data into buffer for http post
      buf := &amp;bytes.Buffer{}
      enc := json.NewEncoder(buf)
      enc.SetEscapeHTML(true)
      enc.Encode(w.Data)
      // Encrypt the data for signature
      mac := hmac.New(sha256.New, []byte(w.Signature))
      mac.Write(buf.Bytes())
      base64Enc := base64.RawURLEncoding.EncodeToString(mac.Sum(nil))
      // Create post request
      client := &amp;http.Client{
             Timeout: time.Duration(5 * time.Second),
      }
      req, err := http.NewRequest(&quot;POST&quot;, w.URL, bytes.NewReader(buf.Bytes()))
      if err != nil {
             ctx.Log().AddField(&quot;Webhook data&quot;, w).Error(err.Error())
      }
      req.Header.Set(&quot;Content-type&quot;, &quot;application/json&quot;)
      req.Header.Set(&quot;Signature&quot;, base64Enc)
  </code></pre>
  <p>Here is 1 version of what I have tried. I'm trying to create the Signature from the response and match it to the signature in the header. I cannot get a match. this doesn't try</p>
  <pre><code> Encoding ascii = Encoding.ASCII;
  
  
          var client_secret = &quot;[Secret]&quot;;
  
          //request body
          var body = &quot;[Responce Body]&quot;;
  
          // signature form header
          var signature = &quot;RwtK6Kr4NOOFs9mjYPpEJWxSJQr23k6uXDktj4QEjGk&quot;;
  
          // uri escape the body
          var calc_body = Uri.EscapeUriString(body);
  
          //url encode te body
          calc_body = WebUtility.UrlEncode(calc_body);
  
          //create the signature HMACSHA256    
          var sig = GenerateSignature(calc_body, client_secret);
  
          //Base64 Url encode the signture
          var calc_sig = Base64UrlEncode(ascii.GetBytes(sig));
  
          //Compare the signature form the header to the calculated cignature
          if (signature == calc_sig)
          {
  
              Console.WriteLine(&quot;Matches&quot;);
  
          }
          else
          {
  
              Console.WriteLine(&quot;Does not match&quot;);
  
          }
      }
  
      private static string GenerateSignature(string data, string signatureKey)
      {
          var keyByte = Encoding.ASCII.GetBytes(signatureKey);
          using (var hmacsha256 = new HMACSHA256(keyByte))
          {
              hmacsha256.ComputeHash(Encoding.ASCII.GetBytes(data));
              return hmacsha256.Hash.Aggregate(&quot;&quot;, (current, t) =&gt; current + t.ToString(&quot;X2&quot;)).ToLower();
          }
      }
  
      static string Base64UrlEncode(byte[] arg)
      {
          var s = Convert.ToBase64String(arg); // Regular base64 encoder
          s = s.Split('=')[0]; // Remove any trailing '='s
          s = s.Replace('+', '-'); // 62nd char of encoding
          s = s.Replace('/', '_'); // 63rd char of encoding
          return s;
      }
  </code></pre>
  <p>I'm not even sure I have the right steps.</p>
  <p>Thanks in advance for any help.</p>