关于node.js:是什么使字符串/令牌在密码上安全?

What makes a string / token cryptographically secure?

如果您需要生成字符串/令牌来认证将来的请求(例如API密钥,电子邮件确认URL等),应考虑哪些因素?

尤其是

  • 是什么使字符串" secure" /"很难猜"?
  • 如何测量/估计"安全量"?
  • 那里的主要标准是什么?

一个实际的例子

让我们从NodeJS中获取这两个输出字符串。

字符串1(通过Node crypto)

1
2
3
4
var crypto = require('crypto');
crypto.randomBytes(48, function (ex, buf) {
  console.log(buf.toString('hex'));
});

字符串2(通过节点UUID)

1
2
var uuid = require('node-uuid');
console.log(uuid.v4());

根据以上概述的概念,哪一个更为安全?为什么?

另外,请随意建议有关该主题的任何入门材料,因为我很难在网上找到有关此主题的文章。


What makes the string"secure" /"very hard to guess"?

字符串或令牌不能是加密安全的,因为它是静态的。

密码安全(伪)随机数生成器(CS(P)RNG)的概念描述了生成的数字是不可预测的。这是程序的属性,而不是单个数字的属性。

How is the"security amount" measured / estimated?

这取决于所使用的随机性源,因为其中一些是黑匣子。您可以产生很多随机性,看看是否在其中找到了一些模式。有一些可用的测试套件,但是您必须考虑您的应用程序以及需要这些随机数的速度。请求大量随机性可能会耗尽池,然后产生不足的随机数。

What are the main standards out there?

使用系统/框架指定的加密安全随机性源。如果您想信任文档,则Node.js的crypto.randomBytes()是其中之一。

A practical example

node-uuid内部使用crypto.randomBytes(),因此其背后具有基本相同的随机强度,但是如果crypto.randomBytes()不可用,它将降级为Math.random()Math.random()不是加密安全的。如果要在浏览器中使用加密安全的随机值,则需要查询Web Crypto API的getRandomValues()