用 CyberChef 手動驗 X-Device-Signature
webhook 簽章對唔到嗰陣,第一件事係要判斷邊一邊錯——你嗰邊定我哋呢邊。CyberChef 可以畀你喺 browser 度跑 UnifyPort 完全一樣嘅簽章算法,用 handler 收到嘅同一組 input,三十秒出結果。
UnifyPort 究竟簽乜嘢
每次投遞只要配咗 signing secret,就會帶三個 header:
簽章係咁計嘅:
Debug 前貼幾條喺 mon 邊:
- timestamp 同 body 中間嗰隻 byte 係 ASCII 點(
.),唔係換行。 raw_body係指我哋發出嘅原始 byte——喺你嗰邊做任何 JSON parse、去空白、unicode 正規化之前。- hex output 係細階。如果同大階 digest 比,會 false-negative。
CyberChef recipe
喺 CyberChef 度按順序將兩個 operation 拖入 recipe pane:
- 1. HMAC——將 Hashing function 設成
SHA256。把 signing secret paste 落 Key,Type 揀UTF8。 - 2. To Hex——Delimiter 留空,Bytes per line 設
0。咁可以出到無 space 嘅細階 hex string,啱晒 header。
喺 Input pane 度 paste 嘅嘢必須係 <timestamp>.<raw_body>——例如:
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。
常見問題
- 我點樣手動驗 UnifyPort webhook 簽章?
- 喺 CyberChef 度加 HMAC(Hashing function 揀 SHA256,signing secret 當 Key、encoding 用 UTF8),跟住接 To Hex(delimiter 留空,bytes per line 設 0)。將
<timestamp>.<raw_body>一字不漏 paste 落 Input pane。Output 應該同X-Device-Signatureheader 逐個 byte 都一樣。 - 點解我嘅簽章同 UnifyPort 發過嚟嗰個對唔到?
- 三個常見原因:(1)你用咗錯嘅 signing secret——核對下個值同 dashboard 見到嗰個係咪一樣;(2)body 喺驗證之前畀人改過——重新 emit 嘅 JSON、去空白、或者 unicode 正規化全部都會搞爛個 digest;(3)timestamp 讀錯 header——淨係
X-Device-Timestamp先有簽,唔係 framework 嗰個 Date header。 - 將 signing secret paste 入 CyberChef 安唔安全?
- 官方 host 嘅 CyberChef 係純靜態嘅 client-side bundle——secret 唔會離開你個 browser,亦都冇 server 端 logging。如果你想做到零暴露,可以 clone 個 repository 喺本地開
index.html,或者用 DevToys——完全 offline 嘅 desktop equivalent。
手動驗完之後
將等效邏輯搬入 handler。大多數語言嘅 standard library 都有 primitive:Node 嘅 crypto.createHmac、Python 嘅 hmac.new、Go 嘅 hmac.New。比對一定要用 constant-time function(timingSafeEqual、hmac.compare_digest、hmac.Equal)——絕對唔好用 ==。