在Node / Express中散列,加密并保存密码

时间:2013-10-08 09:57:47

标签: javascript node.js hash express passwords

我在Node的标准库中需要加密模块。 我有这个POST路由处理注册表单:

app.post('/superadmin/add-account', function(req, res) {

  // Shorthand variable
  var doc = req.body;

  crypto.randomBytes(32, function(err, buf) {

    if (err) throw err;

    // Sanitise and transform user input
    ... 

    // Validate user input
    ... 

    var errors = validator.getErrors();

    // Generate new object data
    doc.salt = buf; 
    doc.pass = doc.salt + 'justForNow';

    console.log(doc);

当我输出doc(req.body)时,我得到了一些对我来说很奇怪的值...... 控制台中输出的buf主要由charachter组成,类似于里面有问号的盒子。它是否正确?但是当我将buf保存到doc.salt并输出时,我得到的东西完全没有......“慢速缓冲器是C5 A3 E3 ....等等”

Q1:我是否必须使用crypto.randomBytes()生成的盐做一些特殊的事情(用什么来解析?)才能使用字符串连接或保存它?

Q2: crypto.randomBytes()函数存在于异步和同步版本中。我使用异步版本,但我真的不知道为什么? = PI认为async callbaks主要用于处理可能需要时间的I / O操作......或者我使用此函数的回调版本,因为它实际上是一个复杂的过程,可能需要一些时间并锁定系统用于som MS如果我使用同步版本?

Q3:我还没有,但是我会继续使用The Crypto模块的哈希函数来哈希盐+密码并将其保存到数据库。我知道我必须创建一个这样的var:

var sha256 = crypto.createHash('sha256'); 

但我不明白我现在如何使用它。

1 个答案:

答案 0 :(得分:1)

使用crypto.randomBytes()生成随机字节时,解析字节没有什么特别之处,因为它们是随机的。随机字节由两个十六进制数字组成,因此如果您使用buffer.toString(),则该字节可以映射到00FF之间的任何UTF-8数字。

使用randomBytes()函数时,您会得到SlowBuffer,这是Buffer的内部类。

<SlowBuffer 76 46 14 02>
// v F \u0014 \u0002

如果两个十六进制数字的UTF-8表示不存在,则会出现乱码:

<Buffer 96>
// �
<SlowBuffer 9e 94>
// ��

对于第二个问题,是否要使用randomBytes()函数的同步版本的异步取决于您。函数使用的CPU时间量还取决于您要求的随机字节数。如果你想要一个兆字节的随机字节,你会在相当长的时间内阻塞事件循环,但是如果你想要10个随机字节,那只需要几毫秒。

在大多数情况下,如果您将操作放在HTTP处理程序中,则应使用异步版本,因为您希望不惜一切代价避免阻塞事件循环。这是不该做的一个例子:

app.post('/', function(req, res) {
  crypto.randomBytes(1000000000);
});

通过执行上述操作,您将停止服务器处理任何其他传入的HTTP请求。

关于您的上一个问题,您已创建了哈希对象,但尚未更新其数据或计算其摘要。分别使用hash.update()hash.digest()作为哈希的字符串表示形式:

var crypto = require('crypto');
var hash = crypto.createHash('sha256').update(data).digest('hex');

hash.update()函数接受两个参数,一大块数据和一个编码,而hash.digest()接受编码。