Skip to content
smallPict

การยืนยันตัวตนและลายเซ็น HMAC-SHA256

ความปลอดภัยของคำขอด้วย HMAC-SHA256, การตรวจสอบเวลา และการป้องกัน Replay Attack

เพื่อความปลอดภัยสูงสุดในการใช้งานจริง SmallPict กำหนดให้คำขอที่มีการเปลี่ยนแปลงข้อมูลต้องมีลายเซ็น HMAC-SHA256 เพื่อป้องกันการดัดแปลงข้อมูลระหว่างทางและสกัดกั้นการโจมตีแบบ Replay Attack


ส่วนหัว HTTP ที่จำเป็น

ส่วนหัวประเภทคำอธิบาย
X-API-KeyStringคีย์ API สาธารณะของคุณ (sp_live_... หรือ sp_test_...)
X-TimestampIntegerเวลา Unix timestamp ในหน่วยวินาที UTC (เช่น 1716301234)
X-SignatureStringลายเซ็น HMAC-SHA256 ที่คำนวณได้ในรูปแบบฐานสิบหก

อัลกอริทึมการสร้างลายเซ็น

ลายเซ็นเกิดจากการคำนวณ HMAC-SHA256 โดยใช้ Secret Key ของคุณร่วมกับข้อความรูปแบบมาตรฐานดังนี้:

TEXT
CANONICAL_STRING = HTTP_METHOD + "\n" + REQUEST_PATH + "\n" + TIMESTAMP + "\n" + SHA256_HEX(REQUEST_BODY)

ข้อควรระวัง: ค่า X-Timestamp จะต้องไม่คลาดเคลื่อนจากเวลาเซิร์ฟเวอร์ SmallPict เกิน ±300 วินาที (5 นาที) มิฉะนั้นคำขอจะถูกปฏิเสธด้วยรหัส 401 Unauthorized


ตัวอย่างโค้ดการสร้างลายเซ็น

Node.js / TypeScript

TypeScript
import crypto from "crypto";
function generateSignature(method: string, path: string, timestamp: number, body: string, secretKey: string): string {  const bodyHash = crypto.createHash("sha256").update(body).digest("hex");  const canonical = `${method.toUpperCase()}\n${path}\n${timestamp}\n${bodyHash}`;  return crypto.createHmac("sha256", secretKey).update(canonical).digest("hex");}

Python

Python
import hmac, hashlib
def generate_signature(method: str, path: str, timestamp: int, body: bytes, secret_key: str) -> str:    body_hash = hashlib.sha256(body).hexdigest()    canonical = f"{method.upper()}\n{path}\n{timestamp}\n{body_hash}"    return hmac.new(secret_key.encode('utf-8'), canonical.encode('utf-8'), hashlib.sha256).hexdigest()

Golang

Go
package main
import (    "crypto/hmac"    "crypto/sha256"    "encoding/hex"    "fmt"    "strings")
func GenerateSignature(method, path string, timestamp int64, body []byte, secretKey string) string {    bodyHash := sha256.Sum256(body)    canonical := fmt.Sprintf("%s\n%s\n%d\n%s", strings.ToUpper(method), path, timestamp, hex.EncodeToString(bodyHash[:]))    mac := hmac.New(sha256.New, []byte(secretKey))    mac.Write([]byte(canonical))    return hex.EncodeToString(mac.Sum(nil))}