我知道,这是一个简单的问题,也许与其他问题相似,但是我在这些问题中找不到我的答案,所以我要提出一个新问题。
我想了解检查数据库密码的过程。我知道他们使用加密和哈希算法,但是我不明白他们如何检查这些存储的值并将它们与输入字段中提供的用户密码进行比较以进行验证?
例如,正如我在许多答案中所读到的那样,您无法检测到MD5哈希密码,而密码只有一种直接算法,那么数据库如何使用这些哈希?
答案 0 :(得分:2)
在检查用户名/密码组合时,登录信息通过POST
发送到服务器。然后,服务器端脚本(如果构建正确)将重新应用与它们最初用于散列信息的逻辑相同。
例如,如果脚本在注册期间调用md5($password)
,则用户的密码将存储在MD5的数据库中。尝试以该用户身份登录时,登录脚本必须POST
使用相同的注册哈希方法-在这种情况下为md5($password)
,以便可以将两个MD5字符串进行相互比较。
通过这种方式,您比较哈希值。由于将相同的哈希机制应用于相同的字符串将始终给出相同的哈希输出,因此,通过简单地比较相同的哈希,您将比较相同的原始字符串。这样您才能知道用户是否获得了正确的密码。
此外,请记住,加密和哈希是 not the same thing 。如果您知道加密中使用的密钥,解密就变得微不足道了。相反,散列是单向加密,因此“破解”散列的唯一方法是蛮力(猜测密码可能是什么,然后比较散列的输出)。
最后,请注意,MD5为highly insecure(即使有盐)和should NOT be used for password storage。相反,您应该考虑使用PASSWORD_BCRYPT
或PASSWORD_ARGON2I
之类的安全算法,password_hash()
和password_verify()
(如果使用PHP)。
答案 1 :(得分:0)
在大多数情况下,客户端会对密码进行哈希处理和加盐处理,然后(通常)将包含登录数据的POST
请求发送到某个API。
然后,此API在服务器端调用SQL(或NoSQL)数据库,因此用户无法直接与数据库中与其所需内容无关的任何部分进行交互。此时,您需要做的(服务器端)是将用户(客户端)提交的哈希密码/加盐密码与数据库中存储的密码进行比较。如果一切都匹配,则表明登录成功(假设用户名,会话令牌等也有效)。
注意:
MD5 isn't considered secure anymore,所以最好的选择是使用SHA-256
之类的哈希。
答案 2 :(得分:0)
非常简单的术语:
散列接受任意大小的输入并为其生成一个“校验和”。无论输入的是字母“ a”还是“莎士比亚的完整作品”,生成的哈希的长度都相同。对于MD5,此类哈希可以表示为32个字符的字符串。您可以使用any online MD5 hash genarator对此进行测试。
注意
现在,不用在数据库中存储密码,而是可以存储该密码的哈希。要检查密码,只需再次对输入字段中输入的值进行哈希处理即可。如果它生成的密码与数据库中存储的密码相同,则假定密码正确,并且实际密码永远不会真正存储在数据库中。
我说假定,因为从理论上讲,两个不同的输入可以生成相同的哈希,尽管在输入密码的情况下这种可能性很小(对于某些实际崩溃,示例,请参见this question under Crypto.StackExchange )。
彩虹表和反向哈希
彩虹表基本上是已计算哈希值的典型密码的列表。使用MD5的示例:
5f4dcc3b5aa765d61d8327deb882cf99 => password
dc647eb65e6711e155375218212b3964 => Password
您可以使用许多所谓的md5 decryptors中的任何一个轻松地查询这样的列表(同样,请注意:它们并不是真正的解密-只是将散列与已知值列表)。
如果某人可以访问您的数据库并获取您的密码哈希列表,则该列表可以用于推断某些用户的密码,如果
Salt 基本上是指在生成哈希之前添加一些额外的信息,以使生成的哈希不太可能出现在彩虹列表中。例如,假设您不仅哈希密码,还哈希用户名和密码的组合; password
将生成哈希5f4dcc3b5aa765d61d8327deb882cf99
,该哈希可能会出现在每个彩虹表中,而khkhkkPassword
将生成be2d1a6255d12f44b8a44f25aea41516
,可能不会出现在其中任何一个哈希表中。
这些都是基础知识,此处针对MD5所述的原理对于其他算法应相同。但是请注意,MD5长期以来一直被认为是不安全的,应该使用其他更强大的选项。有several options,在许多情况下,无论您使用哪种编程语言或框架,都有工具或库以及最佳实践,可以帮助简化选择和实现。