题
在选择合适的算法用于会话哈希时,大小确实很重要。
我最近读了 文章 它建议使用漩涡为会话ID创建哈希。惠而浦会生成一个128个字符的哈希字符串,这太大了吗?
该计划是将会话放在DB中。使用64个字符字段(SHA256),96个字符字段(SHA384)或128个字符字段(漩涡)之间是否有很多区别?惠而浦最初提出的论点之一是速度与其他算法,但是查看速度结果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;
}
解决方案
创建哈希的时间并不重要,只要您的数据库正确索引,存储方法也不应该是主要因素。
但是,每次都必须以cookie作为cookie来传输哈希人的要求。大型饼干可以为每个请求增加少量的额外时间。看 Yahoo!的页面性能最佳实践 了解更多信息。较小的饼干,因此较小的哈希有好处。
总体而言,大哈希功能可能没有道理。对于他们有限的范围,Good Old MD5和SHA1可能是会话令牌背后的来源。
其他提示
是的,大小很重要。
如果太短,您会冒着碰撞的风险。您还可以使攻击者通过蛮力攻击找到别人的会话是实用的。
太长的时间太少了,但是会话ID的每个字节都必须通过每个请求将从浏览器传输到服务器,因此,如果您真的非常优化事物,则可能不希望ID太长。
不过,您不必使用哈希算法的所有位 - 没有什么可以阻止您使用漩涡之类的东西,然后只需拿起前128位(HEX中的32个字符)。实际上,128位的长度也是一个很好的下限。
但是,正如埃里克森(Erickson)指出的那样,使用哈希(Hash)有些奇怪。除非您的熵至少与所使用的ID的长度一样多,否则您很容易受到猜测对哈希输入的攻击。
这篇文章何时尝试阅读它,但我想不出有充分的理由将哈希作为会话标识符。会话标识符应该是不可预测的;鉴于文章的标题,听起来像是作者承认这一原则。那么,为什么不使用加密随机数生成器生成会话标识符呢?
哈希采取输入,如果该输入是可以预测的,那么哈希也是不好的。
SHA1或MD5可能足以满足您的需求。实际上,碰撞的可能性很小,以至于可能永远不会发生。
最终,这完全取决于您所需的安全级别。还要记住,更长的哈希既更昂贵,也需要更多的存储空间。