2 回答
TA贡献1883条经验 获得超3个赞
问题是它的每次加密每次都不一样,所以它永远无法与数据库中的相匹配。
这是正常的 bcrypt 行为。
bcrypt 每次都返回不同的散列,因为它将不同的随机值合并到散列中。这被称为“盐”。它可以防止人们使用“彩虹表”攻击您的散列密码,这是一个预先生成的表,将密码散列映射回他们的密码。salt 意味着密码不是一个散列,而是 2^16 个。太多无法存储。
盐作为散列密码的一部分存储。因此bcrypt.CompareHashAndPassword(encryptedPassword, plainPassword)
可以plainPassword
使用相同的盐进行加密encryptedPassword
并进行比较。
我在这里做错了什么?
您正在尝试将生成的散列密码与存储的散列密码进行比较。至少我当然希望它是存储在数据库中的散列密码。
相反,您想要的是将存储的散列密码与用户输入的普通密码进行比较。
// Normally this comes from user input and is *never* stored
plainPassword := "supersekret"
// The encrypted password is stored in the database
db.Where(&User{Username: strings.ToLower(data.Username)}).First(&user).Pluck("password", &result)
encryptedPassword := []byte(result[0])
// Check if the stored encrypted password matches "supersekret"
encryptionErr := bcrypt.CompareHashAndPassword(encryptedPassword, plainPassword)
if encryptionErr == nil {
fmt.Println("Greetings Professor Falken")
} else {
fmt.Println(encryptionErr)
}
TA贡献1770条经验 获得超3个赞
bcrypt散列算法在设计上会在您每次调用它时生成一个不同的加密字符串(它是加盐的)。如果您有要检查的明文密码和数据库中的密文,您应该能够将这两件事传递给bcrypt.CompareHashAndPassword
. 调整您的代码:
var result []string
db.Where(&User{Username: strings.ToLower(data.Username)})
.First(&user)
.Pluck("password", &result)
encryptionErr := bcrypt.CompareHashAndPassword([]byte(result[0]), []byte(data.Password))
您不需要bcrypt.GenerateFromPassword再打电话;正如您所注意到的,它将生成一个不同的加密密码,并且几乎不可能比较两者是否相等。
- 2 回答
- 0 关注
- 747 浏览
添加回答
举报