php会话ID有多独特

时间:2008-09-26 10:41:51

标签: php session guid

php会话ID有多独特?我从各种各样的事情中得到了印象,我不应该依赖两个用户永远不会得到相同的sessionid。这不是GUID吗?

10 个答案:

答案 0 :(得分:64)

发货时不是很独特。在默认配置中,它是各种事物的散列的结果,包括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

答案 1 :(得分:36)

Session_id确实可以重复,但概率非常低。如果您的网站流量公平,可能会在您的网站生活中发生一次,并且会让一个用户厌倦一次会话。

除非您希望为银行业建立一个非常高流量的网站或服务,否则不值得关注。

答案 2 :(得分:12)

如果您想知道默认情况下PHP如何生成会话ID,请查看Github上的源代码。它当然不是随机的,并且基于这些成分的哈希值(默认值:md5)(参见代码片段的第310行):

    客户
  1. IP地址
  2. 当前时间
  3. PHP线性同余生成器 - 伪随机数生成器(PRNG)
  4. 特定于操作系统的随机源 - 如果操作系统有可用的随机源(例如/ dev / urandom)
  5. 如果操作系统有可用的随机源,那么为了成为会话ID而生成的ID的强度很高( / dev / urandom和其他OS随机源(通常)是加密安全的PRNG )。但如果它没有那么它是令人满意的。

    生成会话标识的目标是:

    1. 最小化生成具有相同值的两个会话ID的概率
    2. 使计算生成随机密钥并使用一个非常具有挑战性。
    3. 这是通过PHP的会话生成方法实现的。

      你不能绝对保证唯一性,但概率很低,只能达到两次相同的哈希值,一般来说,不值得担心。

答案 3 :(得分:11)

如果要自定义生成ID的方式,则可以安装备用哈希生成函数(默认情况下,它是通过MD5生成的128位数)。见http://www.php.net/manual/en/session.configuration.php#ini.session.hash-function

有关PHP会话的更多信息,请尝试这篇优秀的文章http://shiflett.org/articles/the-truth-about-sessions,该文章还链接到有关会话固定和劫持的其他文章。

答案 4 :(得分: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万亿中的一个。因此,128位大小的session_id应该足够大。正如其他注释中所述,session_manager也可能会检查新的session_id是否已经存在。

<强>随机性
因此,我认为最大的问题是session_id:s是否生成具有良好的伪随机性。在那你永远不能确定,但​​我建议使用一个众所周知的,经常使用的标准解决方案为此目的(你可能已经做过)。

即使由于检查而避免冲突,session_id的随机性和大小也很重要,因此黑客不能以某种方式进行合格的猜测并且很有可能找到活动的session_id :.

答案 5 :(得分:3)

我还没有找到关于此的确认,但我相信php会在创建具有该ID的会话ID之前检查会话ID是否已存在。

人们担心的会话劫持问题是当有人发现活动用户的会话ID时。这可以通过多种方式加以防范,有关您可以在php.net和this page上看到this paper on session fixation的更多信息

答案 6 :(得分:2)

不,会话ID不是GUID,但是两个用户不应该获得与服务器端存储的会话ID相同的会话ID。

答案 7 :(得分:0)

您可以选择将各种会话与数据库生成唯一字段一起存储在数据库中;合并两者并将其保存在会话变量中,然后检查一个会话ID。

答案 8 :(得分:0)

我知道这篇文章很老了。然而,我在这里添加我的答案,因为我找不到这个问题的相关解决方案,即使在我自己发布了一个类似的问题之后。然而,我从对我的帖子的回复中得到了一个线索。对于那些对算法和解决方案感兴趣的人解释了here。它结合使用会话和不同的 cookie。

简单的算法是这样的

会话处理将通过使用 DB 的自定义类“MySessionHandler”完成

1.就在 session_start 之前,cookie cookie_start_time 被设置为当前时间。此 cookie 的生命周期将与会话的生命周期相同。两者都使用变量 $this->cookieLifeTime 来设置生命周期。

  1. 在会话‘_write’中,我们将该值设置为与 $this->cookieStartTime 相同的数据库表字段 cookie_start_time

  2. 在会话“_read”中,我们进行检查

if($getRowsOfSession[0]['cookie_start_time'] != $this->cookieStartTime).

如果返回 true,则表示这是一个重复的会话,用户被重定向以销毁会话并再次重定向以启动新会话。(总共 2 次重定向)

答案 9 :(得分:-2)

public class SimpleActivatorMenu : MonoBehaviour
{
    // An incredibly simple menu which, when given references
    // to gameobjects in the scene
    public GUIText camSwitchButton;
    ...
}

如果您的用户名不同或唯一,则可以将此代码用于会话