使用HMAC和SHA0256算法签署和验证请求或者返回403。
示例代码
// 准备一个 key 用于加密和解密
const encoder = new TextEncoder()
const secretKeyData = encoder.encode("secret-key")
function byteStringToUint8Array(byteString) {
const ui = new Uint8Array(byteString.length)
for (let i = 0; i < byteString.length; ++i) {
ui[i] = byteString.charCodeAt(i)
}
return ui
}
async function signHmac(value, key) {
const signature = await crypto.subtle.sign(
'HMAC',
key,
new TextEncoder().encode(value),
)
let content = btoa(String.fromCharCode(...new Uint8Array(signature)))
return new Response(encodeURIComponent(content))
}
async function handleRequest(request) {
const key = await crypto.subtle.importKey(
"raw",
secretKeyData,
{ name: "HMAC", hash: "SHA-256" },
false,
["sign", "verify"],
)
const url = new URL(request.url)
const params = url.searchParams
const action = params.get("action")
// 为某个值进行加密
if (action == "sign") {
const value = params.get("value")
return await signHmac(value, key)
}
// 验证加密后的密钥还是否正确
const value = params.get("value")
const mac = params.get("mac")
if (mac == "" || value == ""){
return new Response("mac or value is required", { status: 400 })
}
const receivedMac = byteStringToUint8Array(atob(mac))
const verified = await crypto.subtle.verify(
"HMAC",
key,
receivedMac,
encoder.encode(value),
)
if (!verified) {
return new Response("invalid mac", { status: 403 })
}
return new Response("mac is verified")
}
addEventListener("fetch", event => {
event.respondWith(handleRequest(event.request))
})
示例预览
使用导入的secretKeyData,验证请求内容。
相关参考
- 运行时API:addEventListener
- 运行时API:FetchEvent
- 运行时API:Encoding
- 运行时API:Web Crypto