我想创建一个用户登录系统,以便学习。 我有几个问题。
我做了一些研究,发现实现用户登录系统的正确方法是在数据库中存储用户名/ id和密码的加密/散列版本。 当用户登录时,密码在客户端加密(MD5,SHA-1等)并发送到服务器,并与数据库中的密码进行比较。 如果匹配,则用户成功登录。
此实现可防止DBA或程序员在数据库中看到密码的明文。 它还可以防止黑客在传输过程中拦截真实密码。
这是我困惑的地方:
如果黑客知道密码的哈希/加密版本(通过黑客入侵数据库)或DBA,程序员只需简单地读取数据库中的文本即可获得密码的哈希版本。 然后,他们可以轻松地创建一个程序,将这个哈希版本的密码发送到服务器,允许他们成功登录。如果他们可以这样做,加密密码似乎不是很有用。 我想我在这里误解了一些东西。
这是(我上面描述的方式)实现用户登录功能的最流行方式吗? 它是否遵循当前的最佳做法? 我是否必须手动完成所有操作,或者某些数据库是否具有执行相同操作的内置功能? 是否有最常用的方法/方法为网站或网络应用程序执行此操作? 如果是这样,请向我提供详细信息。
我以前的公司使用couchDB存储用户登录信息,包括密码。 他们没有对加密方面做太多的事情。 他们说couchDB会自动加密密码并将其存储在文档中。 我不确定这是否安全。 如果是这样,那对程序员来说非常方便,因为它节省了大量的工作。
这种方式(第3点)是否足以保证正常使用? 其他数据库系统如mySQL有这种能力可以做同样的事情吗? 如果是这样,是否意味着使用mySQL内置方法足够安全?
我不是在寻找一种非常安全的实现用户登录功能的方法。 我更愿意为大多数Web应用程序寻找一种流行,易于实现,正确,安全的方法。 请给我一些建议。 提供的详细信息将非常感谢。
当用户登录时,客户端代码将通过MD5或SHA-1或类似的东西加密密码,然后将此加密密码发送到服务器端,然后将其与数据库中的密码进行比较。 如果匹配,则用户成功登录。
不,不,客户端需要发送未填充的密码。 如果您在客户端散列密码,那么该散列实际上是密码。 这将使加密散列的安全性无效。 散列必须在服务器端完成。
为了保护传输中的明文密码,需要通过安全通道发送,例如加密的TLS(SSL)连接。
密码应该用一块额外数据是为每个帐户不同咸 。 Salting通过消除明文和散列之间的直接相关来抑制彩虹表攻击。 盐不需要保密,也不需要非常大。 即使是4个随机字节的盐也会使彩虹表攻击的复杂性增加40亿倍。
现在的行业黄金标准是Bcrypt 。 除了盐析,bcrypt通过设计减速因子来进一步增加安全性。
除了结合使用盐来防止彩虹表攻击之外,bcrypt还是一种自适应功能:随着时间的推移,迭代计数可以增加以使其变慢,因此即使计算能力提高,它仍然可以抵抗暴力搜索攻击....从理论上讲,这并不比标准的Blowfish密钥计划更强,但是密钥更新轮次的数量是可配置的; 因此,这个过程可以任意减慢,这有助于阻止对哈希或盐的暴力攻击。
一些澄清: