这实际上远没有那么安全。
在一个理想的世界中,您的数据库不在 DMZ 中,而是只能从您的 Web 服务器直接访问,然后使用有限的帐户权限,为了破坏您的数据库并检索您的哈希密码表,我必须:
- 通过以下方式公开您的软件数据库连接变量(帐户/密码)
- 破坏您的 Web 服务器以获取对其的 shell 访问权限 - 或 -
- 利用应用程序中的弱点直接公开其数据库连接变量
- 连接到您的数据库。我可能需要能够从 SSH 到您的 Web 服务器或通过在其上托管受损代码来执行此操作,除非我设法使用某种形式的 IP 欺骗,成功绕过您的数据库背后的任何路由/防火墙(不太可能)。
- 检索表。这对于我通过步骤 1 妥协的帐户可能是不可能的,如果它实际上并没有比较值本身,而是将当前登录尝试的哈希值传递给数据库中的存储过程,该帐户仅限于访问存储的帐户程序。
如果我不能使用您的程序帐户直接读取表格,我基本上已经完成,除非我可以破坏数据库服务器上的管理员帐户或完全破坏数据库服务器的 VM。
这就是在我们讨论您自己的散列方案是否安全之前的全部内容。
就用户名和散列被“隐藏”而言,它们根本不是,即使您使用编译的代码。即使使用十六进制编辑器快速通过,用户名之类的东西也会立即显现出来。
安全性最适用于既服务于实际目的又将原始数据分离为允许将其用作可用信息所需的最小分区的层,同时仅以最小形式传递必要的相关信息,而不是尽可能地传递数据本身
你的方法把所有的鸡蛋放在一个篮子里
我通过网络的必要步骤是:
- 找到一种方法来公开您的代码以供下载。
而已。如果我让您的网络服务器出现故障,并且您的代码隐藏文件能够直接被拉下,那么您就完成了。我什至不需要对网络服务器进行更深入的妥协,而不是任何可能导致这种情况的事情(这可能会根据您是否将它们放在其他网络可读目录中而有所不同)。或者,如果我在您的代码中发现一个漏洞,我可能会让它直接吐出存储的用户名和哈希值。当然,仍然有同样的可能性完全破坏您的 Web 服务器。
没有办法减缓这样的攻击向量,假设您在某个给定级别的漏洞达到其他级别之前检测到它:单个漏洞会立即暴露所有内容。即使我们谈论的是已编译的软件,熟练的攻击者现在不仅会知道您的散列算法,而且如果您正在使用一种算法,也会知道您的胡椒,以及有效地访问您的散列和加盐密码表。
更简单地说第二个原则,您的软件本身实际上并不需要直接知道给定用户的存储密码来对其进行身份验证。它只需要知道它提供的密码是否与存储的密码相同,这是数据库可以为其确定的密码,以防止您的软件使用的凭据恶意访问数据库(除了尝试从提供给软件的存储过程中进行暴力破解之外,您可能会根据尝试次数和速度检测到并关闭)。
除非没有其他选择,否则不要推出自己的身份验证,或者您确定您确实知道您尝试做的所有事情背后的所有理由,并且愿意重复可能比您看到更多更好的评论的努力将永远让你的通过。这不值得你花时间,而且它几乎总是会导致一些比已建立的库或包更不安全的东西。
如果您认为自己通过做一些不同于行业标准做法的事情而变得聪明,那么请认真思考这些做法背后是否真的有很好的理由。
一旦用户凭据掌握在其他人手中,即使您对它们进行了哈希处理——即使您知道自己在做什么并且对它们进行了很好的哈希处理(当人们尝试使用自己的安全性时很少出现这种情况),您也必须假设它们受到了损害。这真的只是时间问题。您最好的哈希努力最多只是延迟,您有一个窗口通知用户并锁定帐户,直到密码被重置。