我需要澄清一些关于用户身份验证的事情,因为我想知道它的正确完成,
有人告诉我,身份验证是一个关注安全性的过程。因此,应尽可能从客户端隐藏身份验证过程,并且客户端应仅接收标志值(1 =密码正确且经过身份验证,-1 =密码错误)和/或经过身份验证的用户的用户名。所以它应该是一个应该在后端发生的SQL操作。因此,详细过程应该是,客户端表单将用户名和散列/加密密码发送给SQL,SQL进行身份验证,并将带有用户名的1 / -1作为返回值和输出发送给客户端。
但是当我在网上搜索时,在用户身份验证上,情况并非如此,我在网上看到的所有线程,无论是应用程序是Windows还是网页,开发人员都会进行两项操作:
在SQL Server中,用户名搜索密码的saltHash值,然后将saltHash值和PasswordHash一起返回到客户端表单/或业务层
在客户端或BLL中,使用输入的密码和返回的saltHash值生成PasswordHash,然后将此passwordHash与返回的passwordHash进行比较。如果匹配密码正确,如果密码不正确。
这实际上是开发人员编写代码以在登录事件中对用户进行身份验证的方式吗?如果是这样,基本上密码比较发生在客户端(无论是在表单中还是在业务层中),那么通过将实际的saltHash和passwordHash暴露给客户端会不会带来巨大的安全风险?
如果有人可以给我写一些代码来演示SQL和C#的登录/认证过程,那将是一件令人高兴的事!
PS-当你回复时请不要使用LINQ,LINQ to SQL或实体框架。目前我不知道他们。还在学习它们。请从Ado .NET回复
感谢
答案 0 :(得分:4)
这是一个更大的利弊讨论,很难说它一般。客户端哈希的优点:
服务器端哈希的优点:
其他一些指导原则:
以下是有关如何针对客户端与服务器方案进行密码哈希处理的一些指导原则。
如果服务器上有散列:
如果客户端上有散列:
答案 1 :(得分:2)
客户端/服务器应用程序和Web应用程序之间的方法可能相同,但是直接访问SQL数据库的Windows应用程序是另一回事。您可能确实希望避免泄露哈希密码,但盐并不需要是私有的。您可以为用户和哈希客户端获取salt,然后比较服务器端。
我不知道SQL是否有实际的密码哈希算法(mcrypt,PBKDF2等),或者仅限于像SHA系列这样的纯加密算法,但是服务器外部散列的好处是你可以选择你的哈希算法。你也可以围绕它构建一些逻辑。例如,您可以存储针对单个用户使用的哈希算法,然后如果它在将来中断,您可以在下次登录时将其更新为更安全的算法。
您还必须意识到,无论您做什么,除了SQL身份验证之外,其实际安全性都很小。修改程序以忽略SQL服务器响应的内容并继续进行,就像登录成功一样,这是相当简单的。如果您需要实际的安全性,那么您需要一个位于客户端和数据库之间的应用程序服务器。通过简单的身份验证来完成程序,查看它的作用并直接或在其他程序中使用该信息也是微不足道的。
关于重用,将认证分离到单独的模块并在两个应用程序中重用该模块将是更好的方法。 ASP.NET内置了一些robust authentication,因此我会将其视为使用或作为示例。 Crypto.HashPassword()
已经使用了当前接受的最佳做法,只要您为每个用户提供相对较长(例如8个字符)的随机盐。
答案 2 :(得分:0)
我会使用以下方法获取随机盐,但我不能在登录用户事件中使用它,因为即使用户输入正确的信用证,它也将返回失败的身份验证。这是因为登录表单中输入的密码将使用随机盐进行哈希处理,此盐与此用户的数据库中的内容不同
private static byte[] GetSalt()
{
RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
byte[] b = new byte[32];
rng.GetBytes(b);
return b;
}
答案 3 :(得分:0)
这是用户表结构
CREATE TABLE [dbo].[Users](
[UserId] [int] NOT NULL IDENTITY(1,1) PRIMARY KEY,
[LoginName] [varchar](256) NOT NULL UNIQUE,
[UserName] [varchar](256) NOT NULL,
[EmailAddress] [varchar](256) NULL,
[IsActive] [bit] NOT NULL,
[UserPasswordHash] [varbinary](64) NULL,
[UserPasswordSalt] [varbinary](32) NULL
)
GO