Compareing slice of byte

I have a html form (userName and Password), I use MySQL database and store user’s password as a varchar, I use bcrypt.GenerateFromPassword to encrypte password and after that I use
hex.EncodeToString to convert slice of bytes into a string and only after that I insert password into database. On ‘Log In’ page i have also html inputs (userEmail, and password), I make a sql query to get password, then use hex.DecodeString to convert password into slice of byte and after that I convert user’s input (in login page) into slice of byte and compare to slices. And problem is they do not match. Please emplain why, and give a better approach to make all this staff. BTW I compare bytes by bcrypt.CompareHashAndPassword

Can you please provide an example piece of code?

Something minified that shows your problem?

Just use a hardcoded password for the example.

I get users password
password := r.FormValue("userPassword")
After encrypting and converting slice of byte into string by hex

 encryptPassword, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.MinCost)
	if err != nil {
		http.Error(w, "Server error", http.StatusInternalServerError)
		return
	}

	hexPass := hex.EncodeToString(encryptPassword)

insert into db

stmt, es := db.Prepare("INSERT INTO userinfo VALUES(?,?,?,?,?,?)")
	if es != nil {
		panic(es.Error())
	}
	_, er := stmt.Exec(email, firstName, lastName, hexPass, age, "Bayzakova 116")
	if er != nil {
		panic(er.Error())
	}

this was sign up page

now log in page

loginPassword := r.FormValue("userPassword")

get user’s password

encryptPassword, err := bcrypt.GenerateFromPassword([]byte(loginPassword), bcrypt.MinCost)
	if err != nil {
		http.Error(w, "Server error", http.StatusInternalServerError)
		return
	}

encrypt users entered password

rows, err := db.Query("SELECT userPassword FROM userinfo WHERE userEmail=?", loginEmail)
	defer rows.Close()
	if err != nil {
		panic("retard from select query")
	}
	var userPassword string
	for rows.Next() {
		if err := rows.Scan(&userPassword); err != nil {
			log.Fatal(err)
		}
		fmt.Printf("Akezhan %s\n", userPassword)
	}
	if err := rows.Err(); err != nil {
		log.Fatal(err)
	}

got user’s password from database

decrPass, err := hex.DecodeString(userPassword)
	if err != nil {
		panic("retard alert in decoding")
	}

decoded password from db

err = bcrypt.CompareHashAndPassword(decrPass, encryptPassword )
	if err != nil {
		http.Error(w, "Username and/or password do not match", http.StatusForbidden)
		return
	}

and now comparing user entered password from login page and password from database

  1. I’m not sure why you doe the hex.EncodeToString-dance. string(hash) gives a nicely storable string representation which you can then reuse.
  2. The following code works for me:
package main

import (
	"fmt"

	"golang.org/x/crypto/bcrypt"
)

func main() {
	hash, _ := bcrypt.GenerateFromPassword([]byte("Secret"), bcrypt.MinCost)
	fmt.Println(string(hash), err)

	fmt.Println(bcrypt.CompareHashAndPassword(hash, []byte("Secret")))
}

This function takes the hash on the first argument and the plain text password as the second argument. You do not need to encrypt it yourself.

Docs (emphasis mine):

CompareHashAndPassword compares a bcrypt hashed password with its possible plaintext equivalent. Returns nil on success, or an error on failure.

1 Like

OOOOhhh i think i got you, all i need to do is just send as first argument my encrypted password from db and for second argument i can do somthing like this, [ ]byte(user’sEnteredPasswordFromLoginPage)

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.