来自 GMP 扩展的 PHP gmp_random_range 函数在密码学上是否安全?

Is PHP gmp_random_range function from GMP extension cryptographically secure?

我用PHP写了一个生成随机字符组合的软件。为此,我需要随机生成任意长度的整数。所以我使用 GMP 扩展,尤其是 gmp_random_range()。但是我需要用 link 来证明它是加密安全的。或者至少它足够随机。

GMP 随机函数使用种子 (gmp_random_seed ),如果我不设置种子,一切看起来都足够随机。所以,我想当我没有明确设置种子时,它会从一些可靠的随机源中获取它。我找不到明确说明这种事情的东西。

"Random State Initialization" 所示,在 GMP 文档中,GMP 中包含的唯一随机生成器算法是——

  • Mersenne Twister 算法,
  • 各种大小的线性同余生成元,并且
  • a "default algorithm" 用于 "applications with no special requirements",包括安全要求。

奇怪的是,GMP 文档在 "Random State Seeding" 中说 "method for choosing a seed is critical if the generated numbers are to be used for important applications, such as generating cryptographic keys",尽管 GMP 中包含的 none 算法适用于加密用途。


看起来,您可以在 PHP 中使用 random_bytesrandom_int 来生成加密随机数。唯一剩下的就是将它们提供的数字转换为 arbitrary-precision 数字。*从这个意义上说,GMP 似乎不允许 gmp_random_range 和类似功能的自定义 RNG(除了它提供的那些)。因此,您必须借助 GMP​​ 的算术函数来转换这些随机数 "manually"。我有一个 article 讨论如何将随机数转换为各种分布。要生成给定范围内的均匀随机整数,您需要的算法在那篇文章中称为 RNDINTRNDINTEXC

* 在涉及信息安全的情况下,使用随机数作为非加密 RNG 的种子是不合适的,因为如果给定足够的随机数,攻击者就可以反向推导出种子,即使种子是在一种加密安全方式。


如果您的目标仅仅是生成密码随机字符串,您甚至不需要走 GMP 路线。只需为要生成的每个字符调用 random_int,一次构建一个字符的字符串:

  • 构建允许出现在随机字符串中的字符列表。
  • 对于字符串中的每个字符,用列表大小的最大值调用random_int(这个大小几乎肯定在PHP可以处理的整数范围内),然后附加在列表中的给定随机索引处找到的字符(从 0 开始)。