在我构建的 Web 应用程序上,我不会散列密码。相反,我使用用户的密码对用户名进行对称加密,并将结果存储在密码字段中。我在 dotnet 上使用RijndaelManaged 。
登录时,我再次执行此操作并检查是否匹配。
我的问题是,当越来越多的数据库被黑客入侵时,这有多安全?我在任何时候都不知道用户的真实密码。黑客从 db 得到的是用未知密码加密的用户名。使用散列存在彩虹表问题,但使用这种方法则没有。
已经知道解密的值(用户名)可以更容易地找到密码?
在我构建的 Web 应用程序上,我不会散列密码。相反,我使用用户的密码对用户名进行对称加密,并将结果存储在密码字段中。我在 dotnet 上使用RijndaelManaged 。
登录时,我再次执行此操作并检查是否匹配。
我的问题是,当越来越多的数据库被黑客入侵时,这有多安全?我在任何时候都不知道用户的真实密码。黑客从 db 得到的是用未知密码加密的用户名。使用散列存在彩虹表问题,但使用这种方法则没有。
已经知道解密的值(用户名)可以更容易地找到密码?
你真正做的是散列:你用分组密码构建了一个散列函数。顺便说一句,“以密码为密钥对已知值进行加密”是传统的基于 DES 的 Unix 加密方案的设计方式。
从好的方面来说,您的构造包括用户名,这部分提供了盐的效果:不鼓励并行破解,因为使用相同密码的两个用户最终会得到两个不同的哈希输出。“部分”,因为在更改密码时,用户保留了他的用户名,所以在这里某种形式的并行性仍然是可行的;而且,也许更重要的是,相同的用户名可以在多个 Web 应用程序中使用(例如,'admin'),这使得预先计算的表变得有价值(盐的重点是防止并行性,特别是有效使用预先计算的表)。
不利的一面:
这是自制的建筑。50 年的密码学研究告诉我们,自制密码很少是好的。事实上,我们可以“知道”一个给定的算法是正确的,只有通过其他熟练的研究人员多年的审查,而自制的方案,顾名思义,从来没有得到太多的审查。
这是有限的。Rijndael 是一种分组密码,可以接受高达 256 位的密钥;因此,如果您使用密码作为密钥,那么它必须适合 256 位。这可以防止使用所谓的“密码短语”,它可以通过使用大量空间来存储其熵(人脑不喜欢集中的熵,但对稀释的熵感到满意),密码可能很强大但很容易记住密码。
这太快了,这是您计划中最大的直接问题。使用基本 PC,攻击者每秒可以尝试大量密码,特别是因为现代 PC 具有专用于 AES 的操作码。使用四核 PC,每秒应该能够尝试多达 50 亿个密码。没有多少用户选择的密码可以在这样的猛攻中存活很长时间。
其他答案已经说了 No, "roll your own" is rarely a good password storage scheme and yours is no exception.
我想补充一点:这也不是存储/传达用户名的好方案。
你基本上是在散列。除了:
the username encrypted with an unknown password
. 他也得到了明文。用户名。所以这是一个明文分析,对于某些密码来说,这比暴力破解要容易得多。通常,传输协议对于安全性而言与强大的加密功能一样重要,独立于散列与加密。一个糟糕的协议会使你的函数暴露在它不适合的攻击之下,尤其是像“传递哈希”或“中间人”这样的“侧通道攻击”,它们绕过了攻击者一方的实际加密分析。
您的密码存储方案可能容易受到此类攻击,因为您没有指定用户名是否也以明文形式存储。这样做会使您的方案遭受上述攻击。不以明文形式存储它可能需要如上所述容易受到攻击的传输协议。
在您的情况下,这里有一些关于传输协议的额外想法,稍微概括一下:
如果您没有对“传递哈希”攻击采取任何措施,那么您的方案比其他许多方案都差。攻击者既不需要破解你的数据库也不需要破解你的密码。他通过嗅探网络流量免费获得他需要的东西。
HTTPS 可能就足够了,尽管它可以通过“中间人”来解决:用户不会检查身份验证证书,是吗?攻击者只需打开与您的用户的未经身份验证但加密的连接以及与您的任何预期连接。
额外的挑战-响应方案可能会增加安全性。在登录之前,客户端会收到一个一次性随机字符串(挑战),他需要将其构建到哈希中(响应)。攻击者无法重用嗅探到的哈希,因为挑战也没有被重用。
但同样,没有必要“滚动你自己”。
TL;DR:使用 scrypt。当有一个非常好的标准时,为什么要自己推出呢?
(我认为 scrypt 优于 bcrypt,但 bcrypt 仍然比自己成长好几英里。)
到目前为止,您缺少的一件事是拉伸。想象一下,你被黑了,你的数据库被转储到了 pastebin 上——这可能发生在我们最好的人身上。
无论您做什么,使用 123456 或其他前 20 名密码之一的人都会被发现,他们不应该得到更好的结果。对于选择了中等好的密码的人来说,如果攻击者每次输入所花费的时间是微秒或秒的数量级,这会有所不同。
您也没有撒盐 - 想象一下您的两个 Web 应用程序被黑客入侵,并且一个人的帐户使用相同的用户名和相同的密码。在我看来,攻击者将在两个转储中获得相同的密文,告诉他们有一个免费破解一赠一的优惠。