4

在选择正确的算法用于会话哈希时,大小是否重要。

我最近阅读了这篇文章,它建议使用漩涡为会话 ID 创建哈希。Whirlpool 生成一个 128 字符的哈希字符串,这个是不是太大了?

计划是将会话哈希存储在数据库中。使用 64 个字符字段 (sha256)、96 个字符字段 (sha384) 或 128 个字符字段 (whirlpool) 之间有很大区别吗?惠而浦最初的论点之一是速度与其他算法的对比,但从速度结果来看,sha384 并不算太糟糕。

可以选择截断散列以使其小于 128 个字符。

我确实修改了原始代码片段,以允许根据需要更改算法。

更新:有一些关于字符串被散列的讨论,所以我已经包含了代码。


function generateUniqueId($maxLength = null) {
    $entropy = '';

    // try ssl first
    if (function_exists('openssl_random_pseudo_bytes')) {
        $entropy = openssl_random_pseudo_bytes(64, $strong);
        // skip ssl since it wasn't using the strong algo
        if($strong !== true) {
            $entropy = '';
        }
    }

    // add some basic mt_rand/uniqid combo
    $entropy .= uniqid(mt_rand(), true);

    // try to read from the windows RNG
    if (class_exists('COM')) {
        try {
            $com = new COM('CAPICOM.Utilities.1');
            $entropy .= base64_decode($com->GetRandom(64, 0));
        } catch (Exception $ex) {
        }
    }

    // try to read from the unix RNG
    if (is_readable('/dev/urandom')) {
        $h = fopen('/dev/urandom', 'rb');
        $entropy .= fread($h, 64);
        fclose($h);
    }

    // create hash
    $hash = hash('whirlpool', $entropy);
    // truncate hash if max length imposed
    if ($maxLength) {
        return substr($hash, 0, $maxLength);
    }
    return $hash;
}
4

4 回答 4

3

创建哈希所需的时间并不重要,只要您的数据库正确索引,存储方法也不应该是主要因素。

但是,每次都必须将哈希值与客户端的请求一起传输,通常作为 cookie 传输。大型 cookie 可以为每个请求增加少量的额外时间。有关详细信息,请参阅Yahoo! 的页面性能最佳实践。较小的 cookie,因此较小的散列,有好处。

总体而言,大型散列函数可能不合理。对于它们有限的范围,好的旧 md5 和 sha1 可能只是作为会话令牌背后的来源。

于 2010-06-22T00:44:54.873 回答
2

是的,大小很重要。

如果它太短,您将面临碰撞的风险。您还可以让攻击者通过蛮力攻击找到其他人的会话。

太长没那么重要,但是会话 ID 的每个字节都必须随着每个请求从浏览器传输到服务器,所以如果你真的在优化事情,你可能不想要一个太长的 ID。

但是,您不必使用散列算法的所有位 - 没有什么可以阻止您使用 Whirlpool 之类的东西,然后只使用前 128 位(十六进制中的 32 个字符)。实际上,128 位也是一个很好的长度下限。

然而,正如埃里克森所指出的,使用散列有点奇怪。除非您的输入熵至少与您使用的 ID 长度一样多,否则您很容易受到猜测哈希输入的攻击。

于 2010-06-22T09:56:00.803 回答
1

当我尝试阅读这篇文章时,它会超时,但我想不出使用哈希作为会话标识符的充分理由。会话标识符应该是不可预测的;鉴于文章的标题,听起来作者承认了这一原则。那么,为什么不使用加密随机数生成器来生成会话标识符呢?

哈希接受输入,如果输入是可预测的,那么哈希也是可预测的,这很糟糕。

于 2010-06-22T00:51:29.627 回答
0

SHA1 或 MD5 可能足以满足您的需求。在实践中,碰撞的概率非常小,以至于它可能永远不会发生。

但最终,这一切都取决于您所需的安全级别。还要记住,更长的哈希计算成本更高,并且需要更多的存储空间。

于 2010-06-22T00:42:34.263 回答