为什么Ruby #hash方法是随机的?
我只是注意到每次启动
Ruby时#hash的返回值都会改变:
$irb 2.0.0-p353 :001 > "".hash 2313425349783613115 2.0.0-p353 :002 > exit $irb 2.0.0-p353 :001 > "".hash 4543564897974813688 2.0.0-p353 :002 > exit 我查看了MRI源,看看为什么会发生这种情况: st_index_t rb_str_hash(VALUE str) { int e = ENCODING_GET(str); if (e && rb_enc_str_coderange(str) == ENC_CODERANGE_7BIT) { e = 0; } return rb_memhash((const void *)RSTRING_PTR(str),RSTRING_LEN(str)) ^ e; } 事实证明rb_memhash是在random.c中定义的: st_index_t rb_memhash(const void *ptr,long len) { sip_uint64_t h = sip_hash24(sipseed.key,ptr,len); #ifdef HAVE_UINT64_T return (st_index_t)h; #else return (st_index_t)(h.u32[0] ^ h.u32[1]); #endif } 虽然我找不到ruby_sip_hash24是什么,但我认为它不是一个确定性函数. 经过一番混乱之后,我设法找到了Tanaka Akira的this commit,由于“避免算法复杂性攻击”,将rb_str_hash更改为使用rb_memhash.那是什么意思? 谢谢! 解决方法
正如提交消息所说,它应该避免
algorithmic complexity attacks.
通过使用rb_memhash,每次启动新的ruby执行上下文时,哈希结果都将被随机化.否则,如果没有随机化,攻击者就会知道算法,并且可以找出可能用作DoS攻击的最坏情况行为. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |