请说明在 Node.js 环境下,生成密码哈希及验证哈希值的常用实现方式,并解释其安全理由。
考察说明
考查对 Node.js 中哈希生成与验证的掌握,以及安全实践意识。
回答思路
- 【回答框架 1】Node.js 中可使用内置 crypto 模块生成哈希。常见做法是选择强哈希算法,如 SHA-256,调用 crypto.createHash 并 update 数据后 digest 获取十六进制或 base64 结果。
- 【回答框架 2】对于密码存储,应使用专门密码哈希算法,如 bcrypt(bcryptjs 或 bcrypt 库)或 scrypt(crypto.scrypt),它们内置盐和慢速哈希,显著提高暴力破解成本。
- 【回答框架 3】验证哈希值时,不能直接比较两个哈希字符串,需使用时间安全比较函数,如 crypto.timingSafeEqual,防止时序攻击。同时如需解码哈希,需提取盐和算法参数。
- 【回答框架 4】生成哈希时,应确保盐的随机性和足够长度,密码明文不应记录日志。验证流程应统一处理错误情况,避免泄露用户存在性等信息。
- 【关键点 1】crypto.createHash('sha256') 可用于一般数据完整性哈希。
- 【关键点 2】密码哈希优先选 bcrypt 或 scrypt,内置盐和慢哈希。
- 【关键点 3】验证时用 timingSafeEqual 防时序攻击。
- 【关键点 4】盐需随机且唯一,避免重复使用。
- 【易错点 1】不要直接用普通哈希(如 SHA-256)存储密码,无盐易被彩虹表破解。
- 【易错点 2】不要用字符串直接比较哈希,可能受时序攻击。
- 【易错点 3】避免过度裁剪哈希长度或忽略盐的随机性。