核心价值使用 `crypto.subtle` 在 Edge 环境中计算与验证 HMAC-SHA256 签名。结合时间戳限制请求时效并采用常数时间比较降低侧信道风险。签名验证实现export const runtime = 'edge'

const SECRET = 'super-secret'

const SKEW = 300

async function hmac(input: ArrayBuffer) {

const enc = new TextEncoder()

const key = await crypto.subtle.importKey('raw', enc.encode(SECRET), { name: 'HMAC', hash: 'SHA-256' }, false, ['sign'])

const mac = await crypto.subtle.sign('HMAC', key, input)

return new Uint8Array(mac)

}

function constantTimeEqual(a: Uint8Array, b: Uint8Array) {

if (a.length !== b.length) return false

let diff = 0

for (let i = 0; i < a.length; i++) diff |= a[i] ^ b[i]

return diff === 0

}

function parseSig(sig: string) {

const s = sig.replace(/^sha256=/, '')

const raw = atob(s)

const buf = new Uint8Array(raw.length)

for (let i = 0; i < raw.length; i++) buf[i] = raw.charCodeAt(i)

return buf

}

export async function POST(req: Request) {

const ts = Number(req.headers.get('x-timestamp') || 0)

const sig = req.headers.get('x-signature') || ''

if (!ts || !sig) return new Response('Unauthorized', { status: 401 })

const now = Math.floor(Date.now() / 1000)

if (Math.abs(now - ts) > SKEW) return new Response('Expired', { status: 401 })

const body = await req.arrayBuffer()

const enc = new TextEncoder()

const payload = new Uint8Array(enc.encode(ts.toString()).length + body.byteLength)

payload.set(enc.encode(ts.toString()), 0)

payload.set(new Uint8Array(body), enc.encode(ts.toString()).length)

const mac = await hmac(payload.buffer)

const recv = parseSig(sig)

if (!constantTimeEqual(mac, recv)) return new Response('Unauthorized', { status: 401 })

return Response.json({ ok: true }, { headers: { 'Cache-Control': 'no-store' } })

}

治理建议第三方应携带时间戳与签名,签名覆盖时间戳与请求体;服务端校验后再处理业务。重放防护可结合唯一事件 ID 做去重存储,或依赖上游幂等保证;本文示例提供请求时效限制。结论在 Edge 路由中以 HMAC 验证结合时间戳窗口进行入口治理,可显著降低伪造与重放风险,并保持实现的简洁与高性能。

点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论
立即
投稿

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部