如何使用 randomBytes() 在 node.js 中生成随机 6 位密码

Jus*_*tin 5 javascript random cryptography node.js

我正在尝试6在 Node.js 中生成完全随机的数字,这需要加密安全。这是我的代码:

var crypto = require('crypto');

crypto.randomBytes(2, function(err, buffer) {
    console.log(parseInt(buffer.toString('hex'), 16));
});
Run Code Online (Sandbox Code Playgroud)

问题是结果可能是45数字,因为我们正在从十六进制转换为十进制。有没有办法既保证函数的加密安全randomBytes(),又保证 6 位数的结果?

sch*_*lop 7

Node v14.17 中添加了用于执行此操作的新函数

crypto.randomInt([min, ]max[, callback])
Run Code Online (Sandbox Code Playgroud)

得到一个6位整数。

const crypto = require('crypto');
crypto.randomInt(100000, 999999, (err, n) => {
    if (err) throw err;
    console.log(`Random 6 digit integer: ${n}`);
});
Run Code Online (Sandbox Code Playgroud)

另外,根据文档https://nodejs.org/api/crypto.html#cryptorandomintmin-max-callback,您还应该通过以下方式检查您的最小值和最大值是否是安全整数:

Number.isSafeInteger() 
Run Code Online (Sandbox Code Playgroud)


mek*_*all 3

2 个字节的最大值为 65535,因此如果只使用 2 个字节,则永远不会得到 6 位数字。

使用 3 个字节代替,然后使用以下命令将其减少到 6 位substr

var crypto = require('crypto');
crypto.randomBytes(3, function(err, buffer) {
    console.log(parseInt(buffer.toString('hex'), 16).toString().substr(0,6));
});
Run Code Online (Sandbox Code Playgroud)

另一种解决方案是执行randomBytes直到获得 6 位数字的值:

var crypto = require('crypto');
var secureVal = 0;
function generateSecureVal(cb) {
    crypto.randomBytes(3, function(err, buffer) {
        secureVal = parseInt(buffer.toString('hex'), 16);
        if (secureVal > 999999 || secureVal < 100000) {
            generateSecureVal(cb);
        } else {
            cb();
        }
    });
}

generateSecureVal(function(){
    console.log(secureVal);
});
Run Code Online (Sandbox Code Playgroud)

上面的问题是,理论上它可能会陷入永无休止的循环,并且它很可能会比第一个示例使用更多的 CPU 周期。

  • 不幸的是,第一个选项在加密上并不安全,因为它有偏见。问题是“randomBytes()”返回一个从 0 到“2^24 - 1”的值。这不是十进制的整数,只是二进制或十六进制的整数。诀窍是在不引入偏差的情况下保留尽可能多的完全随机位。第一个函数中的返回值偏向于较低的数字。另一种更好,但不使用模数,因此效率低下。此外,它在深度未知时使用递归 - 这可能会耗尽您的堆栈。 (2认同)