我想生成字符串标记以实现Web应用程序的密码重置功能。它们可以是v4 UUIDs,但不是必需的。
我希望每个令牌都是"安全随机"在this SO question的意义上。应为每个生成的令牌对系统的熵池进行采样。
我找到了生成v4 UUID的uuid包。文档提到
我们使用System.Random StdGen作为我们的随机源。
但我不清楚这是否足够。
我应该使用其他库吗?
答案 0 :(得分:1)
应该在每个生成的令牌上对系统熵池进行采样的要求听起来很可疑。熵通常是稀缺资源。
我们同意/dev/random
肯定是出局的。其他过程可能需要它,它可能导致潜在的拒绝服务等。但首先,/dev/random
在认为熵池不足时阻止,因此它是肯定的否定。另一方面,/dev/urandom
应该完全没问题。有人说它在某些奇怪的情况下会出现问题(比如在无盘机器上启动后),但是不要去那里。
请注意,在大多数系统/dev/[u]random
上都使用相同的算法。区别在于/dev/urandom
永远不会阻塞,但也不一定在每次读取时使用任何新的熵。因此,如果使用/dev/urandom
计为“对系统熵池进行采样”,那么您正确使用它的任何解决方案都可能没问题。
然而,这是以杂质为代价的。从/dev/urandom
读取会迫使我们进入IO
。作为haskellers,我们必须至少考虑替代方案,如果我们放弃熵样本要求,我们很幸运,这开始时似乎很奇怪。
相反,我们可以使用加密安全确定性RNG,并仅从/dev/random
播种。来自cryptonite的ChaChaDRG
是DJB的ChaCha的实现将是一个不错的选择。由于它是确定性的,我们只需要IO
来获得初始种子。之后的一切都是纯粹的。
Cryptonite提供getRandomBytes
,因此您可以调整令牌的长度以满足您的需求。