繁体   English   中英

用户使用单个查询和每用户密码盐登录

[英]User Login with a single query and per-user password salt

我决定使用存储在数据库中的每用户盐实现用户登录。 盐的前缀为密码,密码用SHA进行哈希处理并存储在数据库中。

在过去我没有使用salt时,我会使用典型的方法来计算查询返回的行数,使用用户输入的用户名和密码。 但是,对于每用户salt,您需要先获取salt,然后才能将其与存储的密码哈希进行比较。

因此,为了避免有两个查询(1获取盐和另一个验证输入凭据),我决定根据输入的用户名在单个查询中获取salt和散列密码。 就像是

SELECT users.salt, users.password
        FROM users   
        WHERE username = ?'

然后在服务器端代码(PHP)中,我将salt与输入的密码连接起来,哈希并将其与已经从数据库中获取的密码进行比较。

如果不清楚,我想关键的区别在于,在后一种方法中,我在数据库中完成此操作之前检查PHP中的凭据。

在安全性或其他方面,这种方法是否有任何缺点

您可以在一个查询中完成此操作,如下所示:

SELECT 
   SHA1(CONCAT(users.salt, "password-input")) = users.passwordhash
WHERE 
   username = "username-input"

...在服务器端代码(PHP)中的服务器是哪个? 我来自一个DBMS是服务器而其他一切都是客户端的世界。 我怀疑你把web服务器看作是'服务器端'而DBMS作为一个单独的Gizmo,不一定是服务器本身。 好吧,这就是观点的相对论。 (并且不要让我开始使用X11服务器与客户端!)

是的,在单个操作中简单地收集用户名的salt和salted,哈希密码是合理的,然后在PHP中生成所提供密码和salt的SHA结果,并将其与检索到的哈希密码值进行比较。 它甚至意味着密码不会从PHP传输到数据库服务器,因此无论是否加密通信都是无关紧要的(在PHP和DBMS不在同一台机器上的情况下)。 它还将计算从DBMS卸载到PHP; 这是否有益取决于PHP和DBMS的相对工作负载。

正如另一个答案所指出的,可以通过将用户提供的密码发送到DBMS并让DBMS进行哈希计算来获得答案。 注意简单地引用用户的输入 - 转义它以防止SQL注入。 这可能会使密码暴露在从PHP到DBMS之间的窥探中。 重要的是取决于您的基础设施。

我认为你的方法通常是合理的。 比您使用的查询数量更重要的是,即使用户输入了错误的密码,您是否通过网络检索有效的数据库密码。 您的查询执行此操作,而通过在数据库服务器上使用加密函数,您可以避免这种情况并使事情更安全。

为了使其更加安全,请使用存储过程或函数来隐藏任何通过网络嗅探SQL查询或通过其他方式(例如,导致)的加密类型(或任何甚至被使用的事实)通过使用SQL注入漏洞或通过在错误消息中公开查询来查看查询。

我认为它没有任何缺点。 “gahooa”也给出了一个很好的答案。 它会将处理成本从您的Web服务器转移到您的数据库服务器,但对于哪一个更适合负载而言,这只是一个问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM