在选择用于会话哈希的正确算法时,大小是否重要。
我最近阅读了此article,并建议使用whirlpool为会话ID创建哈希。 Whirlpool生成一个128个字符的哈希字符串,这个太大了吗?
计划是将会话哈希存储在数据库中。可能使用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;
}
答案 0 :(得分:3)
创建哈希所花费的时间并不重要,只要数据库被正确编入索引,存储方法也不应成为主要因素。
但是,哈希必须每次都与客户端的请求一起传输,通常作为cookie。大型Cookie可以为每个请求添加少量额外时间。有关详细信息,请参阅Yahoo!'s page performance best practices。较小的cookie,因此较小的哈希,有好处。
总的来说,大型哈希函数可能不合理。对于它们有限的范围,好的旧md5和sha1可能只是会话令牌背后的源。
答案 1 :(得分:2)
是的,规模很重要。
如果时间太短,则存在碰撞风险。您还可以让攻击者通过暴力攻击找到其他人的会话。
太长的事情更少,但会话ID的每个字节都必须在每次请求时从浏览器传输到服务器,所以如果你真的在优化事情,你可能不会想要一个太长的ID。 / p>
你不必使用哈希算法的所有比特 - 没有什么可以阻止你使用像惠而浦这样的东西,然后只取前128位(十六进制的32个字符)。实际上,128位也是一个很好的下限。
正如埃里克森指出的那样,使用哈希有点奇怪。除非您的输入熵与您使用的ID的长度相同,否则您很容易受到猜测哈希输入的攻击。</ p>
答案 2 :(得分:1)
当我尝试阅读它时文章超时,但我想不出使用哈希作为会话标识符的充分理由。会话标识符应该是不可预测的;鉴于文章的标题,听起来像作者承认这一原则。那么,为什么不使用加密随机数生成器来生成会话标识符?
哈希接受输入,如果该输入是可预测的,那么哈希也是如此,这很糟糕。
答案 3 :(得分:0)
SHA1或MD5可能足以满足您的需求。在实践中,碰撞的可能性很小,很可能永远不会发生。
但最终,这一切都取决于您所需的安全级别。还要记住,较长的哈希计算成本更高,需要更多的存储空间。