例如,在用户注册页面上,告诉人们“您的密码将使用(无论)算法存储为单向哈希值”是否安全。
告诉您的用户您使用哪种散列算法是否安全?
如果它不安全,那么你的哈希函数就是纯垃圾,你不应该使用它。
在任何体面的安全分析中,都假设攻击者已经知道您正在使用的所有软件,因为:
- 没有那么多可能性。
- 根据应用程序的行为和输出可以猜到很多东西。
- 可以窥探您的数据库的攻击者也可能拥有您的 PHP 脚本的副本,因此知道.
- 即使在攻击者不知道你的哈希函数的情况下,也很难量化这种缺乏知识:攻击者不知道到什么程度?
- 特别是,攻击者还可以注册为用户,使用他选择的密码,然后观察生成的哈希值,从而使他能够快速测试任何潜在的哈希函数。
另一方面,明确使用的哈希函数可能会给您带来“有能力的网站所有者”的声誉,这会给技术倾斜的客户带来信心。
从纯粹的技术意义上讲,是的,告诉你的用户你使用哪种算法是安全的——只要算法是好的。这不是秘密信息,试图隐藏它是相当愚蠢的。
但是,如果你发布一个使用 bcrypt 的重大声明,这可能会适得其反。您的用户可能会倾向于选择更弱的密码,假设您的神奇哈希算法可以保证它们的安全。事实上,在这个网站上有几个问题,人们实际上认为使用 bcrypt 使密码强度完全无关紧要。当然不是这样。所以你必须非常小心,不要给你的用户一种错误的安全感。
长话短说:告诉任何感兴趣并且(希望)明白他们仍然需要一个好的密码的人是很好的。但我不会在注册表中添加大信息。人们可能会从中得出错误的结论。
我会说只要您使用的散列算法是安全的,它就是安全的。否则,它可能会激励你去追求你的数据库。
作为用户,我不得不承认,我不介意我注册的网站对于凭据的存储方式更加透明。但不太注重技术的用户可能会吃惊和/或错过您的观点,因此请确保您的目标受众关心这些信息。
无论如何,您的密码方案的强度根本不依赖于它的保密性:它依赖于经过同行评审的密码学。因此,披露您使用的算法并不重要。
如果您的散列/密钥扩展算法是安全的,那么它是安全的,但这不是必需的,也可能不是一个好主意。我建议模糊地告诉用户您的密码是如何存储的(例如“密钥拉伸,其中包括单向函数的多次迭代”),但不要提及确切的算法。
将散列方法(甚至整个身份验证方法)保密是通过 obscurity 实现安全性的一个实例,这通常是不受欢迎的。然而,大多数时候,这种皱眉来自于一种误解,就像人们经常将 Hoare 关于过早优化的名言误解为“不要优化”一样。
安全性不能只依赖于默默无闻,然而,在正确的地方默默无闻当然可以增加安全性。
即使攻击者知道算法的所有细节,密码算法也必须可靠地工作,并且假设他知道。出于这个原因,密码算法通常是完全公开的,没有人会相信“秘密”密码算法。
您的安全策略同样必须将完全披露假设为最坏的情况,并且您的系统必须在这种情况下仍然可靠地工作。
但这并不意味着您绝对需要披露每一个细节。
在较高的层面上模糊地告诉您的用户,您的密码存储策略可能会给用户留下良好的印象,但不会让您特别关注某些事情(包括 schroeder 在上面的评论中指出的可能的责任问题)。默默无闻可能既是一种威慑和延迟攻击者的方式。
确切的算法有点模糊,就像在你的前门上放一个大的、突出的门栓,带有一个隐藏的、受保护的锁缝,以及在离开酒店房间之前把钱放进保险箱。
一个带有隐藏的、受保护的狭缝的大螺栓可能并不比一把便宜的锁更安全,因为你可以用大锤砸门或者把一块巨石扔进花园的门。但是,它会告诉潜在的窃贼你很警惕,并且可能会采取其他他不知道的安全措施,并且闯入另一所房屋可能会更容易。在那个受保护的锁下面甚至可能没有螺栓,它仍然会发挥它的作用。
酒店保险箱通常需要 4 个数字(有时酒店经理也会忘记更改紧急密码0000
)。指纹可以让小偷在 3 分钟内打开保险箱,所以这确实不是很安全。然而,对于酒店房间的窃贼来说,3 分钟是永恒的,每增加一分钟就有被抓到的风险——他们很少在房间里总共停留超过 3 分钟。这意味着与将您的钱和劳力士放在桌子上相比,不安全的保险箱实际上是安全的,只是因为这些物品有些模糊和被挡住了。
在线攻击者的情况大致相同。虽然你不太可能在入侵发生时发现它,但入侵者在你之前的可用时间却更少,因为他不仅需要下载密码数据库,还需要找出“秘密”散列算法和盐. 这可能不是很多时间,但它不会花费你任何东西。为什么要放弃它?
如果您告诉攻击者您使用 MD5 对您的密码进行哈希处理,那么他会立即知道他可以在 2 秒内破解您的整个用户数据库,而且您很可能对安全性不太了解,这意味着你是一个非常有吸引力的目标。如果您告诉攻击者您使用“具有多次迭代的密钥拉伸系统”,他可以认为即使破解一个密码也可能需要大量工作。另外,要弄清楚你到底使用什么算法是额外的工作。
如果您的站点只是 20 个要攻击的有趣目标列表中的一个,那么它刚刚移到列表的底部。