密码加密/crypto/bcrypt:哈希密码与给定密码的哈希值不同

12

我对用户密码进行加密并保存到数据库。然后在用户登录时,比较哈希密码和明文密码时,出现了crypto/bcrypt: hashedPassword is not the hash of the given password错误。出了什么问题?

func encryptPassword(password string) (string, error) {
    bytePass := []byte(password)
    hashedPassword, err := bcrypt.GenerateFromPassword(bytePass, bcrypt.DefaultCost)
    if err != nil {
        log.Printf("ERROR:EncryptPassword: %s", err.Error())
    }
    return string(hashedPassword), err
}

func (i *Impl) Register(user User) bool {
    hashedPass, err := encryptPassword(user.Password)
    if err != nil {
        return false
    }

    user.Password = hashedPass

    if err := i.DB.Create(&user).Error; err != nil {
        log.Printf("ERROR:Register: %s", err.Error())
        return false
    }
    return true
}

func (i *Impl) Login(email string, password string) (User, error) {
    var user User
    i.DB.Where("email = ?", email).First(&user)   

    err := bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(password))
    if err != nil {
        log.Printf("ERROR:Login: %s", err.Error())
        return User{}, err
    }

    return user, err
}

请提供一下 user.Password 的内容示例。 - Danilo
例如,这是从数据库中获取的哈希密码 $2a$10$rqHJJTHsxMbtX/5ZjG1mFuWyYbUDW1PLbfwQRN0uChwes38c/0m3e,它是由 123456 生成的。然后我将比较哈希密码和明文密码 123456。@Danilo @JimB - Melih Mucuk
1
Register 接受一个指向 User 的指针,但是在调用 i.DB.Create 时,你使用了一个指向指针的指针。这是有意为之吗? - Danilo
数据库字段的大小为varchar(255),密码中没有空格。@martinstoeckli - Melih Mucuk
1
注意:阅读此内容的各位。我曾遇到过类似的问题。不要将数据库中的哈希密码与密码的哈希值进行比较,而应该将其与明文密码进行比较。[] byte和[] byte的界面让我感到困惑。 - user2312578
显示剩余7条评论
3个回答

9
我的猜测是在您的Register函数中,传递给encryptPassword之前,user.Password为空,因此会导致像您提供的那样($2a$10$rqHJJTHsxMbtX/5ZjG1mFuWyYbUDW1PLbfwQRN0uChwes38c/0m3e)对空密码进行哈希。

是的,您可以使用 fmt.Println(bcrypt.CompareHashAndPassword([]byte("$2a$10$rqHJJTHsxMbtX/5ZjG1mFuWyYbUDW1PLbfwQRN0uChwes38c/0m3e"), []byte{})) 进行简单的验证,它将仅打印 nil。您应该添加一个检查来确保这种情况不会发生在 encryptPassword 中。 - djd

3
我无法确定哪个是哪个,但在您的比较函数中,请确保您将变量放在正确的位置。
bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(password))
           Must be the already hashed PW ^              ^ Plain Text Password to compare

同时确保你实际上获得了要散列的内容,因为你可能得到了一个空密码,但是因为哈希仍然看起来很完整,所以你没有意识到它是空的。


1
user.Password 来自数据库,因此它已经是哈希密码。 - Melih Mucuk
@MelihMucuk 你确定它正在正确地敲打吗?在对其进行哈希处理之前,你是否尝试记录该值是什么? - Datsik

1

我的错误在于认为它比较了两个bcrypt哈希密码,而不是一个哈希密码和您的未加密密码转换为二进制--希望这能帮助到某个人!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接