如果您需要生成一个字符串/令牌来验证未来的请求(例如API密钥,电子邮件确认URL等),应该考虑哪些因素?
特别是- 是什么使得字符串"安全"/"很难猜测"?
- 如何测量/估计"安全量"?
- 主要的标准是什么?
一个实例
让我们从NodeJS中获取这两个输出字符串。
字符串1(通过节点加密)
var crypto = require('crypto');
crypto.randomBytes(48, function (ex, buf) {
console.log(buf.toString('hex'));
});
字符串2(通过节点UUID)
var uuid = require('node-uuid');
console.log(uuid.v4());
基于上面概述的概念,哪一个会更安全,为什么?
另外,请随时建议任何关于这个主题的好的介绍性材料,因为我在网上找不到关于这个主题的文章。
是什么使得字符串"secure"/"very hard to guess"?
字符串或令牌不能加密安全,因为它是静态的。
加密安全(伪)随机数生成器(CS(p)RNG)的概念描述了生成的数字是不可预测的。它是过程的性质,而不是单个数的性质。
如何测量/估计"安全量"?
这取决于所使用的随机源,因为其中一些是黑盒。你可以生成大量的随机性,看看是否能从中找到一些模式。有一些可用的测试套件,但随后您必须考虑您的应用程序以及您需要这些随机数的速度。请求大量的随机性可能会耗尽池,然后产生不足的随机数。
主要的标准是什么?
使用系统/框架指定的加密安全的随机源。Node.js的crypto.randomBytes()
是其中之一,如果你想信任文档。
一个实际例子
node-uuid在内部使用crypto.randomBytes()
,因此它背后本质上具有相同的随机性强度,但如果crypto.randomBytes()
不可用,它将回落到Math.random()
。Math.random()
是不是加密安全的。如果您希望在浏览器中具有加密安全的随机值,则需要查询Web Crypto API的getRandomValues()
。