比较密钥字节
本课属于 Coddy Node.js 学习旅程的“身份验证与安全”单元。第 5 课,共 24 课。
两个不同的 Buffer 对象可以存放相同的字节。用 === 比较它们检查的是对象标识,而不是字节内容是否匹配。对于密钥,请使用 timingSafeEqual。逐字节比较如果在遇到第一个不匹配时就停止,可能会通过耗时泄露信息。这个函数使用恒定时间的字节比较;登录代码的其余部分也必须避免耗时泄露。
const same = token.length === savedToken.length
&& timingSafeEqual(token, savedToken);长度检查很重要,因为 timingSafeEqual 在长度不同时会抛出异常。长度不同时,&& 表达式会跳过比较。入门代码会为你将提供的十六进制字符串解码为 Buffer。重点是返回布尔结果。完整的密码登录流程会先根据尝试登录时提供的密码派生密钥,然后进行比较。
挑战
简单这是一个小型练习项目。项目已提供配置,你只需编辑 exercise.js。
当 given 和 expected 包含相同的字节时,返回 {"same":true},否则返回 false。向 /result 发送 POST 请求,内容为 {"given":"abcd","expected":"abcd"},会返回 true。将 given 改为 abce 或 ab,则会返回 false,且不会抛出异常。输入都是有效的十六进制值。
检查字节长度后,使用导入的 timingSafeEqual 函数的结果。比较编码后的字符串或 Buffer 对象的标识并不是这里要练习的安全操作。
亲手试试
import { timingSafeEqual } from 'node:crypto';
export function exercise(input) {
const given = Buffer.from(input.given, 'hex');
const expected = Buffer.from(input.expected, 'hex');
return { same: given === expected };
}
身份验证与安全中的所有课
自己练习: Express 在线编辑器