PHP有一个uniqid()函数,可以生成各种各样的UUID。
在用法示例中,它显示以下内容:
$token = md5(uniqid());
但在评论中,someone says this:
从唯一ID生成MD5是 天真并且减少了很多的价值 唯一ID,以及提供 重要的(可攻击的)狭窄 MD5域名。这是深刻的 破碎的事情要做。正确的 方法是使用唯一ID 它自己的;它已经适应了 非碰撞。
为什么这是真的,如果是这样的话?如果MD5哈希对于唯一ID(几乎)是唯一的,那么从md5到uniqid会出现什么问题?
答案 0 :(得分:34)
UUID是128位宽,并且具有生成方式固有的唯一性。 MD5散列是128位宽,并不保证唯一,只有较低的碰撞概率。 MD5哈希不小于UUID,因此它对存储没有帮助。
如果您知道散列来自UUID,则攻击起来要容易得多,因为如果您对生成它们的机器一无所知,那么有效UUID的域实际上是可以预测的。
如果您需要提供安全令牌,则需要使用cryptographically secure random number generator.(1)UUID并非设计为加密安全,仅保证唯一。由唯一机器标识符(通常是MAC)和时间限制的单调递增序列仍然是完全有效的UUID,但如果您可以从令牌序列中对单个UUID进行反向工程,则可以高度预测。
答案 1 :(得分:12)
请注意, uniqid()
不会返回UUID ,而是根据当前时间返回“唯一”字符串:
$ php -r 'echo uniqid("prefix_", true);'
prefix_4a8aaada61b0f0.86531181
如果多次这样做,您将得到非常相似的输出字符串,熟悉uniqid()
的每个人都会识别源算法。这样就很容易预测将要生成的下一个ID。
md5()输出的优点,以及特定于应用程序的盐字符串或随机数,更难以猜测字符串:
$ php -r 'echo md5(uniqid("prefix_", true));'
3dbb5221b203888fc0f41f5ef960f51b
与普通uniqid()
不同,每微秒产生非常不同的输出。此外,它不会显示您的“前缀盐”字符串,也不会显示您在引擎盖下使用uniqid()
。在不知道盐的情况下,猜测下一个ID非常困难(认为不可能)。
总之,我不同意评论员的观点,并且总是更喜欢md5()
- 输出而不是普通uniqid()
。
答案 2 :(得分:5)
MD5ing UUID是没有意义的,因为UUID已经是唯一且固定长度(短),属性是人们经常使用MD5开始的一些原因。所以我认为这取决于你计划使用UUID做什么,但一般来说UUID与MD5的一些数据具有相同的属性,为什么两者都有?
答案 3 :(得分:2)
UUID已经是独一无二的了,所以无论如何MD5都没有意义。
关于安全问题,一般情况下,如果攻击者可以预测您将要生成的下一个唯一ID,则可能会受到攻击。如果已知您从UUID生成唯一ID,那么潜在的下一个唯一ID的集合会小得多,从而更有可能发生暴力攻击。
如果攻击者可以从您那里获得大量唯一ID,那么尤其如此,这就是猜测您生成UUID的方案。
答案 4 :(得分:2)
Version 3的UUID已经是MD5了,所以重新做这件事没有意义。但是,我不确定PHP使用的UUID版本。
答案 5 :(得分:0)
另外,MD5实际上是过时的,从2010年开始不会用于任何值得保护的东西--PHI,PII或PCI。美国联邦政府已经加强了这一点,任何不合规的实体都将支付大量的$$$罚款。