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

# Vérifier la signature

> Authentifier chaque notification entrante avant de la traiter.

Chaque requête porte l'en-tête :

```http theme={null}
X-Resocom-Signature: t=<horodatage unix>,v1=<hmac sha256 hexadécimal>
```

La signature couvre la chaîne `"<t>.<corps brut>"`, calculée en HMAC-SHA256
avec votre clé `whsec_`. Rejetez toute requête dont :

* la signature ne correspond pas au corps **brut** reçu (avant tout parsing) ;
* l'horodatage `t` s'écarte de plus de **5 minutes** de l'heure courante
  (anti-rejeu).

## Node.js

```js theme={null}
import { createHmac, timingSafeEqual } from "node:crypto";

// rawBody = corps BRUT de la requête (avant tout parsing JSON)
function verifierSignature(secret, header, rawBody) {
  const match = /^t=(\d+),v1=([0-9a-f]{64})$/.exec(header ?? "");
  if (!match) return false;
  const [, t, v1] = match;
  if (Math.abs(Date.now() / 1000 - Number(t)) > 300) return false;
  const attendu = createHmac("sha256", secret)
    .update(`${t}.${rawBody}`)
    .digest("hex");
  return timingSafeEqual(Buffer.from(attendu, "hex"), Buffer.from(v1, "hex"));
}
```

## Vérification manuelle

```bash theme={null}
# t et corps extraits de la requête reçue
echo -n "${T}.${CORPS_BRUT}" | openssl dgst -sha256 -hmac "${CLE_SIGNATURE}"
```

## Pièges classiques

* **Corps brut obligatoire** : un JSON re-sérialisé après parsing ne
  produira jamais la même signature (ordre des clés, espaces).
* Utilisez une comparaison **à temps constant** (`timingSafeEqual`), jamais
  `===`.
* Après une régénération de clé, les livraisons en cours de reprise sont
  signées avec la **nouvelle** clé à la tentative suivante.
