在您的标题中,您在谈论基本身份验证,我假设您在谈论HTTP 基本身份验证,即浏览器提示您输入密码、编码并通过网络发送。但是,您并不能真正控制使用该方法的机制和加密。通常也不使用它,因为它的安全性较低,并且您不能添加诸如 SALT、一次性密码、验证码等内容。
很可能,您希望使用通过 POST 发送表单数据的 HTML 表单来实现基于表单的身份验证。您应该使用带有证书的 SSL/TLS 确保提交此表单以供一般公众使用。这有助于限制中间人 (MiTM) 攻击的能力,在这种攻击中,攻击者可以窃听和捕获用户名和密码。您可以使用 JavaScript 在客户端进行加密,但您仍然需要预先存储初始密码。我只在几个笔测试中看到过这个实现,但用 JavaScript 来做这样的事情并不常见。
现在,关于加盐和散列,以及类似的一切。这更多地与数据库中凭据的存储有关。通常,您会通过 SSL 保护的表单提交收到未经加密的密码。您不想将实际密码存储在数据库中,因此您对其进行哈希处理并使用哈希算法(例如bcrypt)对其进行加盐。盐+哈希使您可以存储密码而无需直接存储。哈希是一种方法,除非您使用一种称为彩虹表的技术,你将不得不暴力破解每一种可能性,直到你运行算法并得到相同的结果。使用盐会使彩虹表的使用变得更加困难,因为彩虹表必须考虑到盐,而不能只是“标准”彩虹表。
你可以有一个每个用户的盐或一个你普遍使用的盐,一个每个用户的盐会更安全。在数据库的用户表中,您将存储以下内容
- 用户名
- 哈希(盐+密码)
- 该用户的盐
现在,当用户再次登录时,他们会在表单中提交用户名和密码。然后,您想查看它们是否在表中,然后您:
- 在您的数据库中查找提供的用户名并返回哈希和盐
- 获取提供的用户名并使用在 1 中获得的盐重新运行散列函数以进行类似散列的操作(盐+密码在表单上提交)
- 如果在 2 中生成的哈希值与在 1 中从数据库中检索到的 on 匹配,那么您就知道他们提供了正确的密码
关键是不存储实际密码,并且要计算出这组随机字符映射回什么的计算成本很高(即,难以确定真正的密码)。
一些进一步的阅读
更新
OP 询问不通过 SSL 发送:
您需要在此处完成以下操作:(1) 传输中的安全数据和 (2) 静态数据的安全。我们讨论的哈希实现了静态安全。为了在传输过程中保护它,您需要确保通过网络传输的数据以某种方式加密。听起来您不想获得或无法获得 SSL 证书。这通常是最常见的方式。否则,您可以实现更复杂的编程方式,在这种方式中,您拥有自己的私钥和公钥。在使用 PGP 或类似的 JavaScript 实现将数据与您的私钥一起发送之前,您或多或少地对数据进行加密。不推荐这样做,因为您很容易搞砸它,而且它需要 JavaScript,而您的用户可能没有启用它。你仍然使用如上所述的盐渍,
算法(警告 - 需要 JavaScript 或其他客户端语言enbaled)
- 创建一个登录表单,不要在表单中设置提交操作 - 我们不希望通过正常方式发送信息,因为它是机密的,我们没有使用 SSL
- 创建一个用于提交表单的 JavaScript 处理程序,作为处理的一部分,使用您的私钥加密密码字段,然后使用 HTTP post 提交。
- 一旦在服务器上收到,用公钥解密
- 您现在已经通过网络传输了带有加密的实际密码
- 经常更改您的私钥-公钥对以减少妥协或逆转。
- 继续按照上面详述的静止固定。
更新 2
OP 继续提问以了解有关保护会话变量的更多信息:
最好将所有提交都放在 SSL 上以保护窃听。即使你散列你所有的 cookie 数据,如果我可以拦截并且我只需要将散列发回给你,好吧,如果我可以成为 MiTM,我已经拥有它。您应该使用多种因素来限制会话劫持和 CSRF 攻击。与其在这里深入细节,您可能想查看OWASP Top 10并阅读各种安全问题以及如何缓解。OWASP 是学习如何保护 Web 应用程序的顶级资源之一。
您要问的第二个问题是,如果您的服务器端应用程序在传递的用户 ID 上执行基本逻辑,这可以伪造吗?是的,使用会话管理来确定当前用户,不要让客户端在认证后告诉你他们是谁。
这篇文章,也与您提出的问题有关,可能对您有用。