2

我正在使用 Zend Framework 制作一个分类广告网站(出于投资组合的目的,是的,我知道世界没有空间容纳“又一个 Craigslist 克隆”)。我正在尝试实现无需帐户即可发布/编辑/删除的功能。

为此,我觉得我需要在提交后生成一个 Nonce 并将其存储在数据库中。然后通过电子邮件将链接发送给发出 GET 删除请求的用户,如下所示:

http://www.somesite.com/post/delete/?id=123&nonce=2JDXS93JFKS8204HJTHSLDH230945HSLDF

只有用户拥有这个唯一的密钥或随机数,提交后我检查帖子 ID 下的数据库,并确保在删除之前随机数匹配。

我的问题是随机数实际上有多安全。如果我使用 Zend Framework 的Zend_Form_Element_Hash,它会像这样创建散列:

protected function _generateHash()
{
    $this->_hash = md5(
        mt_rand(1,1000000) 
        .  $this->getSalt() 
        .  $this->getName() 
        .  mt_rand(1,1000000)
    );
    $this->setValue($this->_hash);
}

在阅读 mt_rand() 时,一位评论者说这个函数的熵是有限的。所以,如果你想创建随机字符串,无论字符串的长度如何,它只会产生大约 20 亿个不同的字符串。这可能是严重的安全性如果您将此类字符串用于会话标识符、密码等,则会出现问题。 "

由于应用程序中的随机数/令牌的生命周期,可能是用户选择删除帖子之前的几天或几周,我认为有足够的时间来进行潜在的黑客攻击。

我意识到mt_rand()这是一个巨大的升级,从左侧和右侧的视觉映射像素rand()中可以看出。但够了吗?是什么让“ 20 亿个不同的字符串”成为安全问题?randmt_rand

最终,我怎样才能增加 nonce/token/hash 的熵?

4

2 回答 2

1

对于这种安全性,您的输出有多长不仅重要。它计算您用来创建它的随机性。

因为mt_rand()随机性的来源是它的种子和状态(自从它被播种以来你使用它的次数)。更多mt_rand()的调用只会让您对相同的随机源进行更多的重新设置(没有新的熵)。

mt_rand()的种子只有 32 位(小于 128 位的任何东西都会使密码学家怀疑;)

具有 32 位熵的密钥的强度是 40 亿除以(大约)您将生成的密钥数量(例如,在使用 100K 之后,将有 ~1:43000 的机会猜测任何有效密钥,这接近于实际的暴力破解)。

您正在为此添加盐,这使其更强大,因为除了猜测种子攻击者还必须知道盐之外,因此如果盐很长,那么尽管“低”,但总体而言密钥可能非常强熵。

要增加熵,您需要从不同的来源添加更多随机的东西(即使稍微随机也可以,只是提供更少的位),而不是 mt_rand: microtime(),使用的内存量,进程 ID... 或者只是 use /dev/random,它可以收集所有熵得到。

(编辑: uniqid() 的熵很弱,所以在这里没有帮助)

于 2012-03-20T23:18:10.617 回答
1

上面为 md5() 散列函数输入的 Zend 散列生成代码有 1,000,000 X 1,000,000 种不同的可能性。无论输入是什么, md5() 都有 32^16 (1208925819614629174706176) 个可能的结果。平均而言,黑客需要向您的服务器发送 500,000,000,000 个请求才能猜出正确的 nonce。

每分钟 100 个请求,大约需要 3472222 天来破解。

于 2012-03-20T23:19:05.523 回答