NodeJS中crypto.pbkdf2Sync函数执行卡住问题排查求助
pbkdf2Sync执行时卡住?问题出在Buffer的错误使用上
问题重现
你在MEAN Stack里实现密码哈希的逻辑,生成盐没问题,但到pbkdf2Sync就彻底卡住——这个坑我之前也碰到过!先看你的代码:
const crypto = require('crypto'); UserSchema.methods.setPassword = function(password){ console.log('start'); this.salt = crypto.randomBytes(16).toString('hex'); console.log(this.salt); this.hash = crypto.pbkdf2Sync(new Buffer.alloc(password), new Buffer.alloc(this.salt), 1000, 64, 'sha512').toString('hex'); console.log(this.hash); };
控制台只输出start和盐字符串,之后就没动静了,完全卡在哈希计算那一步。
问题根源
罪魁祸首是Buffer.alloc()!这个方法的第一个参数是要创建的Buffer字节长度,不是字符串。当你把password和salt(都是字符串)传进去时,JS会把它们强制转成数字——如果字符串不是合法数字,结果就是0,等于你创建了两个空Buffer。
pbkdf2Sync拿到空的密码和盐之后,底层会陷入异常的计算循环,自然就卡住不动了,根本不会走到打印哈希的那一步。
快速修复
有两种简单的解决办法,选哪个都行:
方案1:直接传字符串(最省心)
crypto.pbkdf2Sync()本身就支持直接传入字符串作为密码和盐,完全不需要手动转Buffer,代码更简洁:
const crypto = require('crypto'); UserSchema.methods.setPassword = function(password){ console.log('start'); this.salt = crypto.randomBytes(16).toString('hex'); console.log(this.salt); // 直接用字符串参数,省掉Buffer转换步骤 this.hash = crypto.pbkdf2Sync(password, this.salt, 1000, 64, 'sha512').toString('hex'); console.log(this.hash); };
方案2:用Buffer.from()正确转字符串
如果你一定要手动处理Buffer,别用alloc,改用Buffer.from()——它就是专门用来从字符串、数组等数据源创建Buffer的:
const crypto = require('crypto'); UserSchema.methods.setPassword = function(password){ console.log('start'); this.salt = crypto.randomBytes(16).toString('hex'); console.log(this.salt); this.hash = crypto.pbkdf2Sync(Buffer.from(password), Buffer.from(this.salt), 1000, 64, 'sha512').toString('hex'); console.log(this.hash); };
验证效果
改完之后再运行,你会发现程序顺利走完流程,控制台会正常输出生成的哈希值,再也不会卡住了。
内容的提问来源于stack exchange,提问作者Syed H




