2009-09-25 21 views
3

我已经决定使用存储在数据库中的每个用户盐来实现用户登录。盐的前缀是用SHA加密并存储在数据库中的密码。用户使用单个查询和每个用户的密码salt登录

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

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

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

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

如果不清楚,我猜测主要的区别在于,在后一种方法中,我正在检查PHP数据库中的凭据。

是否有这个方法的什么缺点,在安全性方面或以其他方式

回答

8

你可以做到这一点在一个这样的查询:

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

记住要适当地逃避用户输入以防止SQL注入。正如我的答案中指出的那样 - 它在PHP和DBMS之间发送密码;如果DBMS与PHP代码不在同一台机器上,这可能会暴露密码以进行侦听。它还使用SHA计算而不是PHP加载DBMS。是否重要取决于PHP和DBMS的相对工作量。 –

+0

我确实考虑过MySQL服务器和PHP之间的数据流。我是否正确地认为,如果你不能相信与数据库的连接的“安全性”,那么你的问题就更大了? – gahooa

+0

谢谢,非常优雅 – zenna

0

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

3

...哪个服务器在服务器端代码(PHP)中?我来自一个DBMS是服务器,其他一切都是客户端的世界。我怀疑你正在将Web服务器视为“服务器端”,将DBMS视为单独的Gizmo,而不一定是服务器本身。啊,这就是观点相对论。 (并且不要让我开始使用X11服务器和客户端!)

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

另一个答案指出,可以通过将用户提供的密码发送到DBMS并让DBMS执行散列计算来获得答案。小心简单地引用用户的输入 - 逃避它,以防止注入SQL。这可能会暴露密码以窥探从PHP到DBMS的旅程。多少重要取决于您的基础设施。

1

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

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

相关问题