2008-09-26 56 views
86

PHP会话ID有多独特?我从我读过的各种东西中得到了印象,我不应该依赖两个用户永远不会获得相同的sessionid。它不是一个GUID?php会话ID有多独特

回答

32

Session_id确实可以重复,但概率非常低。如果您拥有一个流量相当的网站,它可能会在您的网站生活中发生一次,并且只会让一个用户烦扰一次。

这是不值得关心,除非你希望建立一个非常高流量的网站,或为银行业界的服务。

2

没有,会话ID是不是一个GUID,但两个用户不应该得到相同的会话ID,因为他们都存储在服务器端。

+0

请问为什么我要投票呢? – gizmo 2008-09-26 11:08:01

+2

可能是因为服务器端存储不能以任何方式保证唯一性。 唯一性是一回事 - 如果发生碰撞,无论会话存储在何处,它都会发生碰撞。 – 2008-09-26 11:29:50

+0

不是由我,我感谢您的回应(以及其他人)。 - Jalov – Jalov 2008-09-26 11:32:45

3

我还没有找到这样的确认,但我相信PHP检查是否会话ID创建一个与之前的ID已经存在。

会话劫持问题的人担心的是,当有人发现了一个活跃用户的会话ID。这可以通过很多方式来预防,更多关于你可以在php.net上看到this page的信息和this paper on session fixation

+2

...但是如果你只是一个数个银行中的一个php服务器,则不能保证服务器有足够的知识来知道sesssionID是否已被使用。 – djsadinoff 2008-09-26 11:03:26

+0

是的,这是一个很好的观点。 – 2008-09-26 11:06:02

59

这不是很独特的发货。在默认配置中,它是包含gettimeofday(这不是非常独特)结果的散列结果,但如果您担心,应该将其配置为从/ dev/urandom中绘制一些熵,如下所示

ini_set("session.entropy_file", "/dev/urandom"); 
ini_set("session.entropy_length", "512"); 

搜索在the code“php_session_create_id”他们正在使用的实际算法。

编辑为: 有一个由pid播种的DFA随机数生成器,与usecs中的时间混合在一起。这不是一个坚定的唯一性条件especially from a security perspective。使用上面的熵配置。

更新:

由于PHP 5.4.0 session.entropy_file默认的为/ dev/urandom的或 的/ dev/ARANDOM(如果可用)。在PHP 5.3.0中,该指令默认为空,为 。 PHP Manual

5

session_id的大小
假设seesion_id是均匀分布的,并且大小= 128位。假设地球上的每个人每天登录一次,持续1000年的新会话。

num_sesion_ids = 1000*365.25 *7*10**9 < 2**36 
collission_prob < 1 - (1-1/2**82)**(2**36) ≈ 1 - e**-(1/2**46) 
       ≈ 1/2**46 

所以一次或多次碰撞的概率小于7万亿分之一。因此,session_id的128位大小应该足够大。正如其他评论中提到的那样,session_manager可能还会检查新的session_id是否已经存在。

随机性
因此最大的问题,我认为是SESSION_ID是否:■与良好的伪随机生成的。在这一点上你永远无法确定,但我会建议使用一个众所周知的,经常使用的标准解决方案来实现这个目的(你可能已经这么做了)。

即使由于检查而避免了冲突,session_id的随机性和大小也很重要,因此黑客无法以某种方式进行合格的猜测并发现活动session_id:s的概率很大。

10

如果您想了解PHP默认生成会话ID的方式,请查看Github上的源代码。这当然不是随机的,是基于散列(默认:MD5),这些成分的(见代码片段的行310):

  1. 客户端的IP地址
  2. 当前时间
  3. PHP线性同余发生器 - 伪随机数发生器(PRNG)
  4. OS专用随机源 - 如果OS具有可用的随机源(例如/ dev/urandom的)

如果OS具有可用的随机源然后为作为一个会话ID的目的所产生的ID的强度高(的/ dev/urandom的和其他OS随机源(通常)加密的安全的PRNG) 。但如果不是,那么它是令人满意的。

与会话身份生成的目标是:

  1. 减少生成两个会话ID具有相同值的概率
  2. 使得它非常具有挑战性的计算,生成随机密钥,并创下了在使用一个

这是通过PHP的会话生成方法实现的。

你不能绝对保证唯一性,但是两次碰到相同散列的概率非常低,一般来说不值得担心。