# Protecting your webhooks (/webhooks/protecting-your-webhooks)



<Callout>
  You can choose any signing secret, but it is recommended to use a long, random string.
</Callout>

## How the signature is calculated

We calculate the signature using the HMAC SHA256 algorithm. The payload (as json) is the string, and the signing secret is the key.

## Verifying the signature

Below you can find examples of how to verify the signature in different programming languages.

<CodeBlockTabs defaultValue="PHP">
  <CodeBlockTabsList>
    <CodeBlockTabsTrigger value="PHP">
      PHP
    </CodeBlockTabsTrigger>

    <CodeBlockTabsTrigger value="Python">
      Python
    </CodeBlockTabsTrigger>

    <CodeBlockTabsTrigger value="JavaScript">
      JavaScript
    </CodeBlockTabsTrigger>

    <CodeBlockTabsTrigger value="Go">
      Go
    </CodeBlockTabsTrigger>

    <CodeBlockTabsTrigger value="Java">
      Java
    </CodeBlockTabsTrigger>

    <CodeBlockTabsTrigger value="Ruby">
      Ruby
    </CodeBlockTabsTrigger>
  </CodeBlockTabsList>

  <CodeBlockTab value="PHP">
    ```php
    $computedSignature = hash_hmac('sha256', $requestContent, $signingSecret);
    ```
  </CodeBlockTab>

  <CodeBlockTab value="Python">
    ```python
    import hmac
    import hashlib

    computed_signature = hmac.new(signing_secret.encode(), request_content.encode(), hashlib.sha256).hexdigest()
    ```
  </CodeBlockTab>

  <CodeBlockTab value="JavaScript">
    ```javascript
    const crypto = require('crypto');

    const computedSignature = crypto
        .createHmac('sha256', signingSecret)
        .update(requestContent)
        .digest('hex');
    ```
  </CodeBlockTab>

  <CodeBlockTab value="Go">
    ```go
    package main

    import (
        "crypto/hmac"
        "crypto/sha256"
        "encoding/hex"
    )

    func main() {
        signingSecret := []byte("your_signing_secret")
        requestContent := []byte("your_request_content")

        h := hmac.New(sha256.New, signingSecret)
        h.Write(requestContent)
        computedSignature := hex.EncodeToString(h.Sum(nil))

        // Use `computedSignature` as needed
    }
    ```
  </CodeBlockTab>

  <CodeBlockTab value="Java">
    ```java
    import javax.crypto.Mac;
    import javax.crypto.spec.SecretKeySpec;
    import java.util.Base64;
    import java.nio.charset.StandardCharsets;

    public class HmacSha256Example {
        public static void main(String[] args) throws Exception {
            String signingSecret = "your_signing_secret";
            String requestContent = "your_request_content";

            Mac mac = Mac.getInstance("HmacSHA256");
            SecretKeySpec secretKeySpec = new SecretKeySpec(signingSecret.getBytes(StandardCharsets.UTF_8), "HmacSHA256");
            mac.init(secretKeySpec);

            byte[] hmacBytes = mac.doFinal(requestContent.getBytes(StandardCharsets.UTF_8));
            String computedSignature = bytesToHex(hmacBytes);

            // Use `computedSignature` as needed
        }

        private static String bytesToHex(byte[] bytes) {
            StringBuilder hexString = new StringBuilder();
            for (byte b : bytes) {
                String hex = Integer.toHexString(0xff & b);
                if (hex.length() == 1) {
                    hexString.append('0');
                }
                hexString.append(hex);
            }
            return hexString.toString();
        }
    }
    ```
  </CodeBlockTab>

  <CodeBlockTab value="Ruby">
    ```ruby
    require 'openssl'

    computed_signature = OpenSSL::HMAC.hexdigest('sha256', signing_secret, request_content)
    ```
  </CodeBlockTab>
</CodeBlockTabs>
