Php 如何散列数据库的会话ID?

Php 如何散列数据库的会话ID?,php,Php,具体地说,我是用PHP做这件事的,但这个问题不是关于内置的PHP会话机制;我正在为实验/教育目的创建自己的认证系统 在这里,不要创建自己的系统不是一个有用的答案,因为我想理解手头的概念性问题 问题是: 会话ID的敏感程度与密码大致相同,应该使用类似的安全散列来存储 常规加密散列函数由于其速度快,现在被广泛谴责为没有价值。 现代密码散列算法的一些特性使得它们不方便对会话ID进行散列。 让我解释一下 会话ID当然是存储在cookie中的一个长随机字符串-系统将其哈希值与数据库中的哈希会话ID进行比较

具体地说,我是用PHP做这件事的,但这个问题不是关于内置的PHP会话机制;我正在为实验/教育目的创建自己的认证系统

在这里,不要创建自己的系统不是一个有用的答案,因为我想理解手头的概念性问题

问题是:

会话ID的敏感程度与密码大致相同,应该使用类似的安全散列来存储 常规加密散列函数由于其速度快,现在被广泛谴责为没有价值。 现代密码散列算法的一些特性使得它们不方便对会话ID进行散列。 让我解释一下

会话ID当然是存储在cookie中的一个长随机字符串-系统将其哈希值与数据库中的哈希会话ID进行比较,以验证有效会话,查找要使用的会话,并从中知道他们作为哪个用户登录,等等。 与密码不同,会话ID是长的、随机的,并且保证是唯一的,因此为每个会话ID指定一个单独的salt并不是很有价值。因此,您可以使用系统范围的salt,允许您对输入进行一次散列,并根据该散列在数据库中查找会话

但是,密码散列函数至少在PHP中可用的表单总是自动为您生成salt,前提是salt被禁止或不推荐,并将其附加到散列输出中,将输入与散列进行比较涉及使用一个特殊的验证函数,该函数使用与散列一起存储的salt对输入进行散列并进行比较。 这意味着,当对会话ID使用密码散列时,无法根据会话ID快速查找会话,而是需要重新散列输入以分别与系统中的每个会话进行比较,尤其是考虑到这在每个HTTP请求上都会发生,这是不可行的

我考虑过的可能解决办法:

为每个会话指定一个自动递增整数ID,该ID也显示在cookie中。这样,会话ID将更多地用作会话特定的密码,而不是作为密码和ID执行双重任务。整数将用于查找。这仍然不允许有人利用从数据库泄漏或猜测中获得的信息制作cookie来劫持会话;他们需要预先散列的SID,这是一个只出现在用户cookie中的长随机字符串。我可以看到的缺点是,在发生cookie窃取攻击时,攻击者将知道SID对应于哪个会话,而无需计算任何哈希或实际尝试劫持会话。结合数据库泄漏,他们还可以知道会话针对的是哪个用户,等等。不过,这似乎没什么大不了的。此外,我觉得我可能遗漏了一些更大的东西,因为会话管理传统上只使用会话ID(也被视为cookie中的密码),而不是单独的会话ID和特定于会话的密码,这肯定是有原因的。 使用Keccak散列会话ID,并接受会话ID不需要与密码相同级别的数据库泄漏缓解,考虑到应用程序需要对敏感操作(如更改用户密码/电子邮件/等)进行重新身份验证,并且会话同时具有空闲和绝对超时 PHP函数不会生成自己的salt,也不会向输出中添加salt

字符串hash_pbkdf2 string$algo,string$password,string$salt,int$iterations[,int$length=0[,bool$raw_output=false]]


调用者控制输出长度、salt、迭代计数,有45个可供选择。

会话ID的敏感程度与密码的敏感程度基本相同-不,它们不是。它们是在没有HTTPS保护的情况下通过cookie或偶尔在地址栏中传递的排序术语一次性标识符。哈希实际上不执行任何“安全功能”。会话id基于随机值;它只是经过散列处理,以便得到可预测的结果id长度。@CD001我认为OP的观点是,通过一点SQL注入来吐出会话id,可以提供与拥有该用户密码大致相同(尽管是临时)的访问权限;它们只在任何特定的时刻是独一无二的。一个失效的会话id可以在将来的任何时候被回收。@ceejayoz-不一定;除了$\u SESSION['logged\u in']==true之外,可能还有一些额外的身份验证;就其性质而言,会话id必须存在于cookie或URL中,并且除非您的整个站点都使用HTTPS,否则该会话id必须可以不加密地供站点使用,因此可以对其进行嗅探,特别是在公共wifi网络上。因此,在确定用户是否登录时,可能需要额外的https纯身份验证cookie或类似的cookie .