我正在更新我在网站上存储密码的方式,并希望分享我的流程想法以确保我做得正确:
首先,用户将选择我将使用的密码:
function generateHash($password) {
if (defined("CRYPT_BLOWFISH") && CRYPT_BLOWFISH) {
$salt = '$2y$11$' . substr(md5(uniqid(rand(), true)), 0, 22);
return crypt($password, $salt);
}
}
$passToStore = generateHash($userPassword);
然后我将把它存储在一个纯粹用于密码的表中,并将来自users表的自动生成的userId
作为密钥:
userId INT
hashedPassword VARCHAR(22)
forgottenHash VARCHAR(36)
当用户返回并尝试登录时,我将从他们输入的电子邮件(用户名)中提取连接选择查询中的密码。然后检查它们与输入的内容相匹配:
function verify($passwordEntered, $hashedPasswordStored) {
return crypt($passwordEntered, $hashedPasswordStored) == $hashedPassword;
}
如果用户忘记了密码,他们会输入他们的电子邮件地址,我会生成一个随机哈希并使其唯一,添加strtotime
当前时间/日期(进入forgottenHash
),然后发送一个链接,让他们点击他们的电子邮件和随机哈希作为密钥和URL。
如果他们点击链接并且哈希匹配具有该电子邮件地址的用户,我将删除存储的哈希密码并让他们创建一个新密码。我关注重置密码的思维过程,但对我来说似乎是对的。但后来我不是黑客。
这是管理密码的好方法还是有更好的方法?
答案 0 :(得分:3)
正如评论中已经提到的其他人一样,有散列功能。他们还会为您生成安全的盐:
// Hash a new password for storing in the database.
// The function automatically generates a cryptographically safe salt.
$hashToStoreInDb = password_hash($password, PASSWORD_BCRYPT);
// Check if the hash of the entered login password, matches the stored hash.
// The salt and the cost factor will be extracted from $existingHashFromDb.
$isPasswordCorrect = password_verify($password, $existingHashFromDb);
忘记密码功能应该像你提出的那样有点不同。虽然密码哈希通常存储在“users”表中,但您应该为密码重置创建一个单独的表。当用户请求时,您生成一个随机标记,该标记不会从其他用户数据中获取,并在新表中存储哈希以及user-id。您发送给用户的令牌本身。如果用户单击带有令牌的链接,那么您可以再次计算此令牌的哈希并在表中搜索它,如果匹配则允许用户更改密码。