Ручная проверка X-Device-Signature через CyberChef
Когда подпись webhook не совпадает, в первую очередь нужно понять, чья сторона сравнения ошибается — ваша или наша. CyberChef позволяет прогнать ровно тот же алгоритм подписи, что и UnifyPort, в браузере, с теми же входными данными, что видит ваш обработчик — секунд за тридцать.
Что именно подписывает UnifyPort
Каждая доставка с настроенным signing secret приходит с тремя header:
Подпись вычисляется так:
Что стоит держать на виду перед отладкой:
- Байт между timestamp и body — ASCII-точка (
.), а не перевод строки. raw_body— это байты, которые мы отправили, до JSON-парсинга, удаления пробелов, unicode-нормализации на вашей стороне.- hex-вывод — нижний регистр. Сравнение с digest в верхнем регистре даст false-negative.
Рецепт CyberChef
В CyberChef положите в панель recipe две операции по порядку:
- 1. HMAC — поставьте Hashing function в
SHA256. Вставьте signing secret в поле Key, Type —UTF8. - 2. To Hex — Delimiter оставьте пустым, Bytes per line —
0. Получится hex-строка без пробелов в нижнем регистре, ровно как в header.
В панели Input вставьте именно <timestamp>.<raw_body> — например:
Output должен совпасть с X-Device-Signature доставки. Если нет — баг локализован в трёх местах: другой secret, body, изменённый по пути, или вы читаете timestamp из неправильного header.
Когда ручная проверка действительно стоит свеч
- После ротации signing secret. Подтвердит, что новый secret реально дошёл до обработчика, прежде чем грешить на DNS или старый деплой.
- После апгрейда JSON-библиотеки. Некоторые парсеры переотдают body перед передачей валидатору — это легко пропустить, пока подписи внезапно не разойдутся.
- Когда коллега говорит «у меня работает». Оба запускают один и тот же рецепт с одними и теми же входами; тот, у кого digest другой, держит неверный secret.
Про вставку secret в веб-страницу
CyberChef — статический клиентский бандл: всё крутится в вашем браузере, и в официальной хостед-версии secret не покидает машину. Если вы всё равно нервничаете из-за расширений браузера или общих сессий, запустите CyberChef локально (клон репозитория, откройте index.html) или используйте DevToys — полностью офлайн-эквивалент на десктопе. Для боевой ротации signing secret сравнение нужно делать кодом с constant-time-функцией, а не глазами по выводу CyberChef.
После ручной проверки
Переложите эквивалент в обработчик. Большинство языков везут примитив в стандартной библиотеке: crypto.createHmac в Node, hmac.new в Python, hmac.New в Go. Сравнивайте только constant-time-функцией (timingSafeEqual, hmac.compare_digest, hmac.Equal) — никогда не ==.