← 所有工具
我哋啲筆記

CyberChef 手動驗 X-Device-Signature

webhook 簽章對唔到嗰陣,第一件事係要判斷邊一邊錯——你嗰邊定我哋呢邊。CyberChef 可以畀你喺 browser 度跑 UnifyPort 完全一樣嘅簽章算法,用 handler 收到嘅同一組 input,三十秒出結果。

UnifyPort 究竟簽乜嘢

每次投遞只要配咗 signing secret,就會帶三個 header:

X-Device-Delivery-Id: d_01J2K…
X-Device-Timestamp: 1716800000
X-Device-Signature: 9f8c…

簽章係咁計嘅:

X-Device-Signature = hex( HMAC-SHA256( secret, timestamp + "." + raw_body ) )

Debug 前貼幾條喺 mon 邊:

  • timestamp 同 body 中間嗰隻 byte 係 ASCII 點(.),唔係換行。
  • raw_body 係指我哋發出嘅原始 byte——喺你嗰邊做任何 JSON parse、去空白、unicode 正規化之前
  • hex output 係細階。如果同大階 digest 比,會 false-negative。

CyberChef recipe

喺 CyberChef 度按順序將兩個 operation 拖入 recipe pane:

  1. 1. HMAC——將 Hashing function 設成 SHA256。把 signing secret paste 落 KeyTypeUTF8
  2. 2. To Hex——Delimiter 留空,Bytes per line0。咁可以出到無 space 嘅細階 hex string,啱晒 header。

Input pane 度 paste 嘅嘢必須係 <timestamp>.<raw_body>——例如:

1716800000.{"id":"evt_demo","type":"message.received",...}

Output pane 出嘅嘢應該同嗰次投遞嘅 X-Device-Signature 一樣。如果唔一樣,bug 就鎖喺三個位之一:用咗唔同 secret、body 喺途中被改過、或者你讀錯 timestamp header。

呢種手動驗真係派上用場嘅時候

  • 輪換 signing secret 之後。喺你怪 DNS 或者 deploy 未 refresh 之前,先確認新 secret 真係到咗 handler。
  • Upgrade JSON 庫之後。有啲 parser 會喺交畀驗證邏輯之前重新 emit 一次 body——呢啲嘢好易走漏眼,直到簽章突然對唔到。
  • 隊友話「我呢度跑得到」嗰陣。兩個人都跑同一個 recipe、同一組 input;digest 唔同嗰個就係攞錯 secret。

將密鑰 paste 入網頁呢件事

CyberChef 係純靜態嘅 client-side bundle——完全喺你 browser 度跑,官方 host 嘅版本裡面 secret 唔會離開你部機。話雖如此,如果你怕 browser extension 或者 shared session,可以本地跑 CyberChef(clone 個 repo 之後開 index.html)或者用 DevToys——完全 offline 嘅 desktop equivalent。Production 嘅 signing secret 輪換,要用 code 做 constant-time 比對,唔好用對眼睇 CyberChef 嘅 output。

手動驗完之後

將等效邏輯搬入 handler。大多數語言嘅 standard library 都有 primitive:Node 嘅 crypto.createHmac、Python 嘅 hmac.new、Go 嘅 hmac.New。比對一定要用 constant-time function(timingSafeEqualhmac.compare_digesthmac.Equal)——絕對唔好用 ==