我应该在散列之前混淆密码吗?我应该在客户端上对它们进行预散列吗?盐呢?

信息安全 密码 密码管理
2021-08-18 21:21:33

为了好玩,在我的业余时间,我正在为自己的目的创建一个简单的 CMS(希望稍后发布以供更广泛的使用......稍后),使用 PHP。我目前正在研究登录方案,并且有几个问题。

注意:最终结果总是使用河豚和 15 的成本参数通过crypt传递 (通常希望成本参数 15 的长度足以伤害黑客攻击,但又不足以让用户感到沮丧。)

问题 1:假设我使用的是 SSL/TLS:在将密码传递给 bcrypt(使用给定的参数和适当的盐)并将其推送到数据库之前,我真的需要混淆密码吗?

问题 1.a:由于我无法访问 SSL/TLS(目前我的网络主机成本太高),在通过之前在密码上使用漩涡哈希(或来自 sha-2 系列的东西)客户端它对服务器来说是一个“足够好”的安全案例,还是那个哈希容易受到彩虹表攻击?(这假设我试图在帐篷上而不是在银行金库上放置一个帐篷襟翼。银行金库可以负担 SSL/TLS。)

问题2:每次用户再次登录时为密码创建一个新的salt是否值得,还是我只需要在注册时为该用户创建一个具有适当熵的唯一salt,然后离开?

4个回答

Q1:就安全性而言,“混淆”密码对您没有任何好处;它只会使代码更复杂,这是一个坏主意。

Q1a:密码的哈希值是“密码等效”:显示它就足以获得身份验证。所以散列不会改变安全性:这相当于以明文形式交换密码。出于安全考虑,您确实希望使用 SSL——没有它,您将不会获得太多的安全性。实际上,在启用 SSL 之前,您可以忘记crypt()Blowfish 和“15”次迭代计数:缺少 SSL 是一个更广泛的安全问题。crypt()使用 Blowfish 非常好,但在没有受 SSL 保护的密码传输的情况下使用它就像在帐篷襟翼上放一把钢挂锁。

Q2:盐的要点是每个密码实例都是唯一的;足够大的随机盐“概率地”确保了这种唯一性。因此,每当您创建和更改密码时(即添加新用户帐户或用户更改密码时),您都会更改盐值。无需重新更改不会更改的密码。

Q1:假设您以“常规”方式进行操作:

  • 最终用户填写 HTML 表单,
  • 通过 HTTPS 提供服务,
  • 响应通过 HTTPS 返回到您的 webapp 服务器,
  • 它通过受信任的网络连接到您的数据库服务器(即 webapp 服务器和数据库服务器都是安全 LAN 上的安全系统)

然后不,不要在密码到达表单提交中的 webapp (PHP) 代码之前混淆密码。

但是——您正计划使用 PHP crypt(),它为您提供了几种让自己陷入困境的方法,通过使用 MD5 进行修复。为什么不使用为安全密码存储优化的高级库?我不是 PHP 程序员,但PHPass似乎是 fx Wordpress 使用的常见选择。否则,请在 Stack Overflow 上查找“PHP bcrypt”或“PHP scrypt”。

Q1a:如果您不使用 HTTPS,这里没有安全性。你的“帐篷襟翼”类比很贴切,你甚至不会用燧石阻止孩子......基本上,不要这样做。如果您这样做,请放弃所有关于“为了安全”在客户端进行散列的想法。更改为提供 HTTPS 的虚拟主机。

Q2:如果/当最终用户更改他的密码时,您只会创建一个新的盐。否则永远不要更改它,每当您验证用户密码时(即每次用户登录时)都需要salt,因此使用错误的salt,用户将无法登录。

Q1:理论上你不需要进一步混淆密码,除了在散列之前添加盐。这只会增加复杂性,而不是安全价值。

Q1.a:在通过网络发送密码之前散列密码只会防止窃听者读取密码本身。它不会防止重播哈希并以该用户身份登录。连接确实应该通过 SSL。

1)不。混淆更多,以至于管理员无法分辨密码是什么

1a) 让我清楚:您应该始终、始终、始终使用 SSL。

一个更好的问题是;答案相同的是;假设由于您与第三方提供商的合同安排,您与第三方提供商建立了 SSL 连接,但您不想冒他们嗅探您的用户信息(密码,任何东西)的风险。除了球探的荣誉之外,你不信任他们。除此之外,您可以在输入字段上使用金丝雀来确保它也是您发送数据的用户。

答:您可以在发送数据之前在 JS 端进行公钥加密。这与 SSL 的安全性不同,但提供了另一层可以使用的安全性。

我曾经遇到过这种情况,合作伙伴拥有 SSL 证书,并且可以嗅探我们的数据,我们使用了这样的系统。