我正在用 php 创建一个登录系统。我有一个用于电子邮件检查的自定义表,它获取用户注册数据,然后将其移动到表用户。
我想知道创建随机盐并将其与散列密码一起存储在临时用户表上是否安全,或者最好只存储普通密码,然后在用户确认后对其进行散列并创建盐?
我在想用户可以如何使用各种电子邮件地址进行大规模“注册”(不能真正验证)并减慢服务器速度(因为盐和哈希创建功能)。顺便说一句,在导致非触发(我正在使用 MySQL)的情况下创建哈希,因为某些值必须手动添加(创建)。
您可以生成一个长随机盐,将盐添加到密码中,并使用标准加密散列函数(例如 SHA256)对其进行散列。然后将盐和哈希都保存在用户的数据库记录中。切勿存储明文密码!
当您想要验证用户的登录时,您需要做的就是从数据库中检索用户的盐和散列,将盐添加到给定密码并使用相同的散列函数对其进行散列。然后将给定密码的哈希值与数据库中的哈希值进行比较。如果它们匹配,则密码正确。否则,密码不正确。
不要:
如果您真的担心服务器速度变慢,那么只需等到用户单击确认链接即可。然后让用户选择自己的密码并存储其哈希值。通过这种方式,您可以完全避免生成盐和哈希(对于假帐户),并具有不必生成机器密码的优势。
您不应该做的是存储没有良好盐的密码哈希。如果您从 DEV_URANDOM 读取(不要使用 DEV_RANDOM),那么您的服务器应该没有阻塞问题,并且不应该因为盐生成而变慢。
请记住,还有其他方法可以降低服务器速度,例如攻击者可以使用登录表单来引发哈希计算。
顺便说一句,使用像password_hash()这样的适当函数没有理由自己生成盐,该函数将尽力生成安全盐,并且它将使用慢速密钥派生函数 (BCrypt)应该用于密码(不是 SHA-* 甚至 MD5)。