ตรวจ X-Device-Signature ด้วยมือผ่าน CyberChef
เมื่อลายเซ็น webhook ไม่ตรง สิ่งแรกที่ต้องแยกคือ ฝั่งไหน ของการเปรียบเทียบที่ผิด — ของคุณหรือของเรา. CyberChef ช่วยให้คุณรันอัลกอริทึมเซ็นแบบเดียวกับ UnifyPort เป๊ะ ๆ ใน browser ด้วย input ชุดเดียวกับที่ handler เห็น ภายในประมาณ 30 วินาที.
UnifyPort เซ็นอะไรกันแน่
ทุก delivery ที่มีการตั้ง signing secret จะมาพร้อม header สามตัว:
ลายเซ็นคำนวณตามนี้:
ติดไว้ข้างจอก่อน debug:
- ไบต์ที่อยู่ระหว่าง timestamp กับ body คือจุด ASCII (
.) ไม่ใช่ขึ้นบรรทัดใหม่. raw_bodyหมายถึงไบต์ที่เราส่งไป ก่อน ที่ฝั่งคุณจะ parse JSON, ตัดช่องว่าง, หรือทำ unicode normalization.- Output hex เป็นตัวพิมพ์เล็ก. ถ้าเทียบกับ digest ตัวพิมพ์ใหญ่ จะได้ false-negative.
Recipe ของ CyberChef
ใน CyberChef ลาก operation สองตัวต่อไปนี้ลงใน pane recipe ตามลำดับ:
- 1. HMAC — ตั้ง Hashing function เป็น
SHA256. แปะ signing secret ลงในช่อง Key, Type เลือกUTF8. - 2. To Hex — เว้น Delimiter ว่าง, Bytes per line ตั้งเป็น
0. จะได้สตริง hex ตัวพิมพ์เล็กไม่มีช่องว่าง ตรงกับ header.
ใน pane Input แปะให้ตรงคือ <timestamp>.<raw_body> — เช่น:
Output ที่ออกมาควรตรงกับ X-Device-Signature ของ delivery. ถ้าไม่ตรง บัก ถูกล็อกอยู่หนึ่งในสามจุด: ใช้ secret คนละตัว, body ถูกแก้ระหว่างทาง, หรือคุณอ่าน timestamp จาก header ที่ผิด.
เมื่อการเช็กด้วยมือนี้คุ้มจริง ๆ
- หลังหมุน signing secret. ยืนยันว่า secret ใหม่ถึง handler แล้ว ก่อนจะไปโทษ DNS หรือ deploy ค้าง.
- หลัง upgrade ไลบรารี JSON. บาง parser ส่ง body กลับออกอีกครั้งก่อนให้ตัว verify — พลาดได้ง่ายจนกว่าลายเซ็นจะไม่ตรง.
- เมื่อเพื่อนร่วมทีมบอกว่า "เครื่องผมรันได้". ทั้งสองรัน recipe เดียวกันด้วย input เดียวกัน; ใครได้ digest ต่าง คนนั้นถือ secret ผิด.
เรื่องการแปะ secret ลงในหน้าเว็บ
CyberChef เป็น bundle ฝั่ง client แบบสแตติก — รันใน browser ของคุณทั้งหมด, ในเวอร์ชันที่ host อย่างเป็นทางการ secret ไม่ออกจากเครื่อง. ถึงอย่างนั้นถ้ายังไม่สบายใจกับ extension หรือ session ที่ใช้ร่วมกัน ให้รัน CyberChef แบบ local (clone repo แล้วเปิด index.html) หรือใช้ DevToys — เดสก์ท็อปออฟไลน์เทียบเท่า. การหมุน signing secret ใน production ต้องเปรียบเทียบด้วยโค้ดที่ใช้ constant-time function ไม่ใช่จ้อง output ของ CyberChef.
คำถามที่พบบ่อย
- จะยืนยันลายเซ็น webhook ของ UnifyPort ด้วยมือได้อย่างไร?
- ใน CyberChef ให้เพิ่ม HMAC (Hashing function SHA256, signing secret ของคุณเป็น Key แบบ encoding UTF8) ตามด้วย To Hex (delimiter ว่าง, bytes per line 0). แปะ
<timestamp>.<raw_body>ลงใน pane Input ให้ตรงเป๊ะ. Output ควรตรงกับ headerX-Device-Signatureทุกไบต์. - ทำไมลายเซ็นของผมไม่ตรงกับที่ UnifyPort ส่งมา?
- สาเหตุที่พบบ่อยสามอย่าง: (1) คุณใช้ signing secret ผิดตัว — ยืนยันว่าค่าตรงกับที่เห็นใน dashboard; (2) body ถูกแก้ก่อนการยืนยัน — JSON ที่ส่งออกใหม่, การตัดช่องว่าง, หรือ unicode normalization ล้วนทำให้ digest พัง; (3) timestamp ถูกอ่านจาก header ที่ผิด — เซ็นเฉพาะ
X-Device-Timestampเท่านั้น ไม่ใช่ Date header ของ framework. - แปะ signing secret ลงใน CyberChef ปลอดภัยไหม?
- CyberChef ที่ host อย่างเป็นทางการเป็น bundle ฝั่ง client แบบสแตติก — secret ไม่ออกจาก browser ของคุณ และไม่มีการ logging ฝั่งเซิร์ฟเวอร์. ถ้ายังต้องการ exposure เป็นศูนย์ ให้ clone repository แล้วเปิด
index.htmlแบบ local, หรือใช้ DevToys — เดสก์ท็อปออฟไลน์เทียบเท่าแบบสมบูรณ์.
หลังตรวจด้วยมือเสร็จ
ย้าย logic แบบเดียวกันเข้าไปใน handler. ภาษาส่วนใหญ่มี primitive อยู่ใน standard library: crypto.createHmac ของ Node, hmac.new ของ Python, hmac.New ของ Go. เปรียบเทียบต้องใช้ฟังก์ชัน constant-time (timingSafeEqual, hmac.compare_digest, hmac.Equal) — ห้ามใช้ == เด็ดขาด.