我正在一个必须进行身份验证(用户名和密码)的项目中
它还连接到数据库,所以我想我会将用户名和密码存储在那里。但是,在数据库上的表中仅具有文本字段的密码似乎不是一个好主意。
我正在使用C#并连接到2008 Express服务器。谁能(以尽可能多的示例)建议存储这种类型的数据的最佳方法是什么?
附言:如果可以提供充分的理由,我不希望此信息不存储在数据库中
我正在一个必须进行身份验证(用户名和密码)的项目中
它还连接到数据库,所以我想我会将用户名和密码存储在那里。但是,在数据库上的表中仅具有文本字段的密码似乎不是一个好主意。
我正在使用C#并连接到2008 Express服务器。谁能(以尽可能多的示例)建议存储这种类型的数据的最佳方法是什么?
附言:如果可以提供充分的理由,我不希望此信息不存储在数据库中
Answers:
您将密码存储在纯文本字段中是一个可怕的主意,这是正确的。但是,就位置而言,在大多数情况下(您真的会想到(我真的想不出任何反例)),在数据库中存储密码表示是正确的做法。通过表示,我的意思是您想使用盐(每个用户应该有所不同)和安全的1向算法对密码进行哈希处理,然后存储该密码,从而丢弃原始密码。然后,当您要验证密码时,可以对值进行哈希处理(使用相同的哈希算法和盐),并将其与数据库中的哈希值进行比较。
因此,尽管您正在考虑这是一件好事,而且这是一个好问题,但这实际上是(至少)这些问题的重复:
为了进一步说明问题,简单地散列密码并存储的危险在于,如果侵入者拥有您的数据库,他们仍然可以使用所谓的Rainbow表来“解密” 密码。密码(至少显示在彩虹表中的密码)。为了解决这个问题,开发人员在密码中添加了盐,如果正确完成,则使得彩虹攻击根本不可行。请注意,常见的误解是在所有密码中简单地添加相同的唯一且长字符串。虽然这并不可怕,但最好为每个密码添加唯一的盐。阅读更多。
背景 您从不需要,真的,不需要知道用户的密码。您只想验证传入用户是否知道帐户密码。
散列: 通过强大的散列功能存储散列的用户密码(单向加密)。搜索“ c#加密密码”提供了许多示例。
请参阅在线SHA1散列创建器,以了解散列函数产生什么的想法(但不要将SHA1用作散列函数,而应使用SHA256等更强的函数)。
现在,哈希密码意味着您(和数据库小偷)不应该能够将该哈希值还原回原始密码。
如何使用它: 但是,您说,如何使用存储在数据库中的此混搭密码?
当用户登录时,他们会交给您用户名和密码(以其原始文本形式)。您只需使用相同的哈希码对输入的密码进行哈希处理即可获取存储的版本。
因此,比较两个哈希密码(用户名的数据库哈希以及键入的密码和哈希密码)。您可以通过比较哈希值来判断“他们输入的内容”是否与“原始用户输入的密码”相匹配。
额外信用:
问题:如果我有您的数据库,那么我能否像开膛手约翰一样吃饼干,然后开始创建哈希,直到找到与您存储的哈希密码匹配的密码?(因为用户还是会选择简短的字典单词,所以应该很容易)
答:是的,可以。
使用诸如sha-512之类的安全算法作为密钥强化的盐化哈希。
最佳安全实践是根本不存储密码(甚至不加密),而是存储加密密码的盐化哈希(每个密码具有唯一的盐)。
这样,(实际上)不可能检索明文密码。
我将强烈建议您阅读以下文章:彩虹表已足够:您需要了解的有关安全密码方案的信息 [无效链接,请从Internet存档中复制 ]以及如何安全地存储密码。
许多编码员(包括我自己在内)认为他们了解安全性和哈希。可悲的是我们大多数人都没有。
正如您提到需要用户名和密码一样,我可能有点偏离主题,我对这个问题的理解当然不是最好的,但是OpenID是否值得考虑?
如果您使用OpenID,那么如果我正确理解该技术并且用户可以使用他们已经拥有的凭据,那么最终根本就不会存储任何凭据,从而无需创建特定于您的应用程序的新身份。
但是,如果所涉及的应用程序仅用于内部使用,则可能不适合
RPX提供了一种很好的简便方法,可以将OpenID支持集成到应用程序中。
在您的方案中,您可以查看asp.net成员身份,这是一个好习惯,将用户的密码作为哈希字符串存储在数据库中。您可以通过将散列的传入密码与数据库中存储的密码进行比较来对用户进行身份验证。
一切都为此目的而构建,请查看asp.net成员资格
如果您不需要反转哈希,我将使用MD5 / SHA1作为密码。当用户登录时,您可以只加密给定的密码并将其与哈希进行比较。在这种情况下,几乎不可能发生哈希冲突,除非有人获得对数据库的访问权并看到他们已经有冲突的哈希。