如何制作一个安全随机的" Haskell中的字符串标记?

时间:2016-11-03 08:19:45

标签: security haskell random cryptography

我想生成字符串标记以实现Web应用程序的密码重置功能。它们可以是v4 UUIDs,但不是必需的。

我希望每个令牌都是"安全随机"在this SO question的意义上。应为每个生成的令牌对系统的熵池进行采样。

我找到了生成v4 UUID的uuid包。文档提到

  

我们使用System.Random StdGen作为我们的随机源。

但我不清楚这是否足够。

我应该使用其他库吗?

1 个答案:

答案 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,因此您可以调整令牌的长度以满足您的需求。