> ## Documentation Index
> Fetch the complete documentation index at: https://docs.kairoconnect.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Verificación de firma – ejemplos por lenguaje

> Código de ejemplo para validar X-Kairo-Signature en PHP, Python, Node.js y Java

Kairo Shield envía la firma en `X-Kairo-Signature` con formato `sha256={hex}`. Calcule HMAC-SHA256 del cuerpo raw (UTF-8) con su webhook secret y compare el hex **sin** el prefijo.

<Tabs>
  <Tab title="Python">
    ```python theme={null}
    import hmac
    import hashlib

    def verify_kairo_signature(raw_body: bytes, signature_header: str, secret: str) -> bool:
        expected = hmac.new(
            secret.encode("utf-8"),
            raw_body,
            hashlib.sha256,
        ).hexdigest()
        received = signature_header.removeprefix("sha256=")
        return hmac.compare_digest(expected, received)

    # Flask ejemplo:
    # raw_body = request.get_data()
    # signature = request.headers.get("X-Kairo-Signature", "")
    # if not verify_kairo_signature(raw_body, signature, WEBHOOK_SECRET):
    #     return "", 401
    ```
  </Tab>

  <Tab title="Node.js">
    ```javascript theme={null}
    const crypto = require('crypto');

    function verifyKairoSignature(rawBody, signatureHeader, secret) {
      const expected = crypto
        .createHmac('sha256', secret)
        .update(rawBody, 'utf8')
        .digest('hex');
      const received = signatureHeader.replace(/^sha256=/, '');
      return crypto.timingSafeEqual(
        Buffer.from(expected, 'hex'),
        Buffer.from(received, 'hex')
      );
    }
    ```
  </Tab>

  <Tab title="PHP">
    ```php theme={null}
    function verifyKairoSignature(string $rawBody, string $signatureHeader, string $secret): bool {
        $expected = hash_hmac('sha256', $rawBody, $secret, false);
        $received = str_starts_with($signatureHeader, 'sha256=')
            ? substr($signatureHeader, 7)
            : $signatureHeader;
        return hash_equals($expected, $received);
    }
    ```
  </Tab>

  <Tab title="Java">
    ```java theme={null}
    import javax.crypto.Mac;
    import javax.crypto.spec.SecretKeySpec;
    import java.nio.charset.StandardCharsets;

    public static boolean verifyKairoSignature(
            byte[] rawBody, String signatureHeader, String secret) throws Exception {
        Mac mac = Mac.getInstance("HmacSHA256");
        mac.init(new SecretKeySpec(secret.getBytes(StandardCharsets.UTF_8), "HmacSHA256"));
        byte[] hash = mac.doFinal(rawBody);
        StringBuilder sb = new StringBuilder();
        for (byte b : hash) sb.append(String.format("%02x", b));
        String received = signatureHeader.startsWith("sha256=")
            ? signatureHeader.substring(7) : signatureHeader;
        return MessageDigest.isEqual(sb.toString().getBytes(), received.getBytes());
    }
    ```
  </Tab>
</Tabs>

Tras validar la firma, procese el JSON según `X-Kairo-Event` o el campo `event` del payload.
