哈希密钥太短,无法作为bcrypt密码进行身份验证。

huangapple go评论92阅读模式
英文:

hashedSecret too short to be a bcrypted password not auth

问题

我正在从这篇博客文章中适应登录功能。User结构体(见下文)有四个字段:id、name、email和password。你可以在下面看到来自数据库的一行数据。登录函数中的fmt.Println显示查询数据库后用户的信息如下:

 &{3 testuser $2a$10$hS7sth8jIBN2/IXFTWBibu3Ko5BXm9zHO5AJZRAbAOQ04uv.Gs5Ym [116 101 115 116 117 115 101 114 64 103 109 97 105 108 46 99 111 109]}

换句话说,它有id(3)、name(testuser)、哈希密码,但还有一个数字数组,这让我有点惊讶,因为它不在数据库的行中(见下文)。你还会注意到,尽管在数据库的行中可见,但fmt.Println没有显示电子邮件,所以这里似乎有个问题。

当bcrypt在Login函数中比较哈希和密码时,它给出了以下错误:

hashedSecret too short to be a bcrypted password not auth

你能解释一下为什么会出现这个错误吗?

func Login(password, email string) (u *User, err error) {
	u = &User{}
	err = db.QueryRow("select * from users where email=$1 ", email).Scan(&u.Id, &u.Name, &u.Password, &u.Email)
	fmt.Println("u", u)

	if err != nil {
		fmt.Println("err", err)
	}	

	err = bcrypt.CompareHashAndPassword(u.Password, []byte(password))
	if err != nil {
		u = nil
	}
	return
}

我有一个具有以下字段的用户结构体:

type User struct {
	Id       int
	Name     string
	Email    string
	Password []byte
}

我在PostgreSQL中创建了一个表,如下所示:

CREATE TABLE "public"."users" (
	"id" int4 NOT NULL DEFAULT nextval('users_id_seq'::regclass),
	"username" varchar(255) NOT NULL COLLATE "default",
	"email" varchar(255) NOT NULL COLLATE "default",
	"password" bytea 
)
WITH (OIDS=FALSE);

这是数据库中的一行数据:

id |  username  |        email         |                                                          password                                                          
----+------------+----------------------+----------------------------------------------------------------------------------------------------------------------------
  3 | testuser   | testuser@gmail.com   | \x24326124313024685337737468386a49424e322f495846545742696275334b6f3542586d397a484f35414a5a524162414f51303475762e477335596d
英文:

I'm adapting the login function from this blogpost. The User struct (see below) has four fields, id, name, email and password. You can see a row from the database below. The fmt.Printlnin the login function shows the user to be like this after the query to the database

 &{3 testuser $2a$10$hS7sth8jIBN2/IXFTWBibu3Ko5BXm9zHO5AJZRAbAOQ04uv.Gs5Ym [116 101 115 116 117 115 101 114 64 103 109 97 105 108 46 99 111 109]}

In other words, it has the id (3), the name (testuser), the hashed password, but then also an array of numbers which surprised me a bit because it's not in the row from the database (see below). You'll also notice that the fmt.Println is not displaying the email, even though that's visible in the row from the database, so there seems to be a problem here.

When bcrypt compares the hash and the password in the Login function, it's giving me this error

hashedSecret too short to be a bcrypted password not auth

Can you explain why this error's being thrown?

func Login(password, email string) (u *User, err error) {
	u = &User{}
	err = db.QueryRow("select * from users where email=$1 ", email).Scan(&u.Id, &u.Name, &u.Password, &u.Email)
	fmt.Println("u", u)

	if err != nil {
		fmt.Println("err", err)
	}	

	err = bcrypt.CompareHashAndPassword(u.Password, []byte(password))
	if err != nil {
		u = nil
	}
	return
}

I have a user struct with the following fields

type User struct {
	Id       int
	Name     string
	Email    string
	Password []byte
}

I created a table for it in postgres like this

CREATE TABLE "public"."users" (
	"id" int4 NOT NULL DEFAULT nextval('users_id_seq'::regclass),
	"username" varchar(255) NOT NULL COLLATE "default",
	"email" varchar(255) NOT NULL COLLATE "default",
	"password" bytea 
)
WITH (OIDS=FALSE);

this is a row from the database

id |  username  |        email         |                                                          password                                                          
----+------------+----------------------+----------------------------------------------------------------------------------------------------------------------------
  3 | testuser   | testuser@gmail.com   | \x24326124313024685337737468386a49424e322f495846545742696275334b6f3542586d397a484f35414a5a524162414f51303475762e477335596d

答案1

得分: 6

数字数组是电子邮件地址。

package main

import (
	"fmt"
)

func main() {
	email := []byte{116, 101, 115, 116, 117, 115, 101, 114, 64, 103, 109, 97, 105, 108, 46, 99, 111, 109}
	fmt.Println(email)
	fmt.Println(string(email))
}

输出:

[116 101 115 116 117 115 101 114 64 103 109 97 105 108 46 99 111 109]
testuser@gmail.com

进一步研究后,我看到你使用了 select *。不要这样做!你会得到数据库返回的项目,而不一定是你想要的。在返回的字段和顺序上要明确。

根据 select *,使用 CREATE TABLE 定义,你可能得到了 idusernameemailpassword。从你的 Scan 函数中,你将 User 类型的 Id 设置为 idName 设置为 usernamePassword 设置为 emailEmail 设置为 password。换句话说,u.Password 包含了 email(它们具有相同的 Go 数据类型),而 email 太短无法伪装成哈希密码。

selectScan 中匹配字段,例如:

"select id, username, password, email from users where email=$1 "

Scan(&u.Id, &u.Name, &u.Password, &u.Email)
英文:

The array of numbers is the email address.

package main

import (
	"fmt"
)

func main() {
	email := []byte{116, 101, 115, 116, 117, 115, 101, 114, 64, 103, 109, 97, 105, 108, 46, 99, 111, 109}
	fmt.Println(email)
	fmt.Println(string(email))
}

Output:

[116 101 115 116 117 115 101 114 64 103 109 97 105 108 46 99 111 109]
testuser@gmail.com

After further study, I see you have select *. Don't do that! You get items returned by the database, not necessarily what you want. Always be explicit in the fields you want returned and their order.

From the select *, using the CREATE TABLE definition, you likely got id, username, email, and password. From your Scan, you set User type Id to id, Name to username, Password to email, and Email to password. In other words, u.Password contains email (they have the same Go data type) and email is too short to masquerade as a hashed password.

Match the fields in the select and the Scan, for example,

"select id, username, password, email from users where email=$1 "

Scan(&u.Id, &u.Name, &u.Password, &u.Email)

huangapple
  • 本文由 发表于 2014年8月17日 05:22:32
  • 转载请务必保留本文链接:https://go.coder-hub.com/25344109.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定