Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jsf-2/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Node.js 如何在NodeJS中使用生成的nonce并在没有数据库调用的情况下进行验证?_Node.js_Mongodb_Nonce - Fatal编程技术网

Node.js 如何在NodeJS中使用生成的nonce并在没有数据库调用的情况下进行验证?

Node.js 如何在NodeJS中使用生成的nonce并在没有数据库调用的情况下进行验证?,node.js,mongodb,nonce,Node.js,Mongodb,Nonce,我正在生成一个nonce来验证向导步骤,以一个接一个地保护它 我知道如何在nodejs中创建nonce并将其存储在数据库中,以确保它可以一次性使用 但是我想知道,是否有一个想法来生成和验证一个nonce,如上所述,只需使用一次,如果可能的话,可以在一个时间限制(到期)内使用,而无需将其存储在数据库中,只需在一个向导步骤中将其返回给客户机,然后在下一步进行验证 我通常使用下面的方法来生成nonce,对其进行规范化,并将其存储在mongodb中,直到过期,以便mongodb在特定时间后删除它(如果未

我正在生成一个nonce来验证向导步骤,以一个接一个地保护它

我知道如何在nodejs中创建nonce并将其存储在数据库中,以确保它可以一次性使用

但是我想知道,是否有一个想法来生成和验证一个nonce,如上所述,只需使用一次,如果可能的话,可以在一个时间限制(到期)内使用,而无需将其存储在数据库中,只需在一个向导步骤中将其返回给客户机,然后在下一步进行验证

我通常使用下面的方法来生成nonce,对其进行规范化,并将其存储在mongodb中,直到过期,以便mongodb在特定时间后删除它(如果未使用)

var crypto = require('crypto');

crypto.randomBytes(32, function (err, bytes) {
   if (err) {
       next(err);
    } else {
       next(null, normalize(bytes));
    }
});

请建议是否有比此更好的/优化的生成nonce的方法,以及在不调用数据库的情况下处理一次性使用和过期的可能性。

最好使用数据库来存储和验证
nonce
。要限制时间,可以使用到期的mongodb,也可以生成时间戳,然后生成带有时间戳、nonce和私钥的
hmac
。然后将nonce、timestamp和hmac发送到客户端。通过这种方式,您还可以保护时间戳,如果您的数据库不支持mongodb的文档到期,您可以使用特定时间限制nonce。希望它能解释。

不需要数据库调用,就可以使用服务器上的哈希映射之类的东西来存储和检索nonce,并检查时间。如果有会话id或静态用户id,则会有所帮助。然而,与测试过的解决方案(如MongoDB)相比,让服务器生成、保存、获取和维护一个nonce似乎很困难。在一个服务有多个服务器的情况下,会出现另一个问题,即会话从开始到结束,流量必须保持一致。使用一个数据库来获取一个nonce上的真实来源可以修复这一问题


如果在节点服务器上保持nonce的原因是速度/延迟,那么额外的测试和代码可能是值得的。在这种情况下,需要定期扫描nonce的超时,以保持快速搜索

编辑:此答案无法防止重播攻击,因此您需要数据库


存储nonce的原因是为了确保它只能使用一次。这可以防止应答攻击,恶意方可能会拦截有效请求,然后重新传输该请求。验证nonce的额外步骤会阻止重新播放的请求被接受

为了防止某些类型的“重播”攻击,重要的是不仅要知道nonce是唯一的,而且要知道它在以前的请求中没有被使用过。现实世界的例子:银行发行支票簿,每张支票都有一个唯一的号码。如果我给你开一张支票并签字,你就可以把它拿到银行去取钱。银行需要记录每一张已经兑现的支票的号码,否则你只需复印我给你的支票原件,然后再次申请这笔钱

旧答案(我不会删除它,因为它在数学上很优雅:) 如果使用128位的加密随机数,则可以使用
2^(128)
数字。考虑到一个均匀分布的随机数生成器,并且每秒调用一次这样的函数,重复的概率几乎为零

您可以在节点中使用类似的内容(此处转换为
base64

128位是16字节

数学演示 适用的二项分布的概率质量函数为

该函数返回在n次试验中获得k次成功的概率,p为每次试验的成功概率

在我们的例子中,
p=1/(2^128)

累积函数为

其中,总和上的
k
是k下的“下限”,即小于或等于k的最大整数。该累积函数给出了成功次数在0到k之间的概率

但我们需要至少一次成功试验的概率,因为我们不想重复。考虑到

因此

这意味着对于
k=1

在我们的例子中,如果我们在100年内每秒调用一次nonce,我们得到
n=1*60*60*24*365.25*100=3155760000

所以

p=1/(2^128);
n=3155760000;
应用公式

结论
如果使用128位nonce,并且在100年内每秒调用一次nonce,则在100年期间重复所述nonce的概率几乎为零,这意味着几乎不可能。这意味着您不需要数据库。

数据库?为什么?如果您使用功能强大的加密随机数生成器,数千年内重复的概率几乎为零。@JoãoPimentelFerreira我宁愿在node.js进程中根本不存储任何数据,因为这将很难扩展。如果有两个或多个服务器节点,其中生成的nonce存储在客户端连接到的节点以外的另一个节点的内存中,则可能会导致一些错误。这就是为什么存储的数据应该总是存储在Node.js之外。就我个人而言,我会在缓存服务器(如Redis)上使用nonce存储。请检查我的答案。我的观点不是存储在哪里,而是你不需要存储在任何地方。我认为这取决于你正在处理的问题,
nonce
通常存储在一些身份验证方案中,如Hawk,以进行比较,以避免重放攻击。存储nonce的原因是为了确保它只能使用一次。这可以防止回复攻击,其中
p=1/(2^128);
n=3155760000;