Payloads are signed using asymmetric (public-key) cryptography to guarantee
the authenticity of delivered callbacks. Each callback delivery request
includes an X-Signature header field. This field contains a base64-encoded
RSA PKCS#1 v1.5 signature of the SHA-256 digest of the request body buffer.
You can obtain the public key for Webhook authentication from
Webhook.public_key of the corresponding Webhook.
You can obtain the public key for success callback authentication from
GET /public_key/.
GET /public_key/ returns the PEM as a JSON-encoded string — the
response body is "-----BEGIN PUBLIC KEY-----..." (with surrounding
quotes), not a bare PEM body and not a {"key": ...} object. You must
json_decode the response body before passing it to your crypto
library. Passing the raw body (quotes included) to openssl_verify /
crypto.createVerify fails with “Supplied key param cannot be coerced
into a public key”.
Please note that CHIP is not responsible for any financial losses incurred
as a result of failing to implement payload signature verification.
How to verify
The verification process is:
- Read the raw request body (before JSON parsing). The signature is
computed over the bytes as received.
- Decode the
X-Signature header from base64.
- Verify it against the request body using the public key with RSA
PKCS#1 v1.5 padding and a SHA-256 digest.
- Reject the request if verification fails.
Always verify the raw request body. Re-serializing the parsed JSON will
change byte ordering or whitespace and break the signature.
Fetching the public key
GET /public_key/ returns a JSON-encoded PEM string. Decode it before use:
Example (Node.js)
Example (PHP)
Example (Python)