我有一个登录窗口,可以从用户那里获取用户名和密码,我想知道处理密码的最佳方法。用户名只是一个常规的文本框,但是密码是一个密码框。我将用户名直接传递到ViewModel,但仅在使用Code-Behind单击“登录”按钮后,仅在ViewModel上设置Securestring属性。设置密码Securestring后,我想验证。

我现在正在编写Loginbox,但是我还没有完全奏效的模型。我应该如何将密码存储在SQL Server中?我是否只将Securestring的内容写入SQL,然后在用户尝试登录时尝试进行比较?

有帮助吗?

解决方案

您绝不应该存储密码 - 甚至没有加密...

只需存储一个密码(只要以安全的方式实现哈希的范围,就可以防止pasword被检索),并且为了验证,您以相同的方式哈希提供了用户提供的密码并比较结果...

有这样做的标准:

上述标准使使用彩虹桌等很难使计算非常昂贵,因为除了使用盐之外,它使用了几轮...因此,哈希速度慢了1000倍(有1000发子弹),但这正是您想要 - 攻击者将需要进行相同的计算,因此需要用蛮力来实现进攻能力或时间的1000倍...

您可以将结果直接存储为varbinary,也可以在base64--或十六进制字节后将结果存储...固定生成的随机盐)。

其他提示

在我以前的演出中,我们将密码存储为哈希/加密/盐的值(当时使用MD5) VARBINARY(32). 。为了比较以后的密码,而不是尝试解密密码,我们将比较我们存储的加密 +盐度值与正在尝试的密码的加密 +盐度值。如果他们匹配,他们就进入了,如果他们不匹配,他们就没有进来。

哈希工作是在中间层进行的(既用于最初保存密码,又用于稍后进行比较),但是基于SQL Server的示例(为了停止 @Yahia的抱怨,这并不是要告诉您最安全的方法,我只是用一个非常轻巧的示例来说明方法。 MD5对您来说还不够强?您可以使用不同,更复杂的算法以及更高级的盐技术,尤其是在应用程序层中执行哈希的情况):

CREATE TABLE dbo.Users
(
    UserID INT IDENTITY(1,1) PRIMARY KEY,
    Username NVARCHAR(255) NOT NULL UNIQUE,
    PasswordHash VARBINARY(32) NOT NULL
);

创建用户的过程(没有错误处理或预防DUPE,只有伪)。

CREATE PROCEDURE dbo.User_Create
    @Username NVARCHAR(255),
    @Password NVARCHAR(16)
AS
BEGIN
    SET NOCOUNT ON;

    DECLARE @salt NVARCHAR(16) = '$w0rdf1$h';

    INSERT dbo.Users(Username, Password)
        SELECT @Username, 
          CONVERT(VARBINARY(32), HASHBYTES('MD5', @Password + @Salt));
END
GO

现在是对用户进行身份验证的过程。

CREATE PROCEDURE dbo.User_Authenticate
    @Username NVARCHAR(255),
    @Password NVARCHAR(16)
AS
BEGIN
    SET NOCOUNT ON;

    DECLARE @salt NVARCHAR(16) = '$w0rdf1$h';

    IF EXISTS 
    (
      SELECT 1 FROM dbo.Users
        WHERE Username = @Username AND 
        PasswordHash = CONVERT(VARBINARY(32), HASHBYTES('MD5', @Password + @salt))
    )
    BEGIN
        PRINT 'Please, come on in!';
    END
    ELSE
    BEGIN
        PRINT 'You can keep knocking but you cannot come in.';
    END
END
GO

实际上,您可能会在应用程序中执行哈希速度,并将哈希值传递为varbinary(32) - 这使得从任何地方“嗅探”实际的清晰文本密码变得更加困难。而且,您也许也不会用代码将盐存储在纯文本中,而是从其他地方检索的。

这绝对比存储未加密的密码更安全,但是它可以删除检索密码的能力。我认为双赢。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top