Search code examples
gogo-gin

Bcrypt takes a lot of time in go?


I have used bcrypt package with GO gin, the weird thing is when I Bcrypt any password it takes like 500ms to 900ms in response

the code:

package main

import (
    "github.com/gin-gonic/gin"
    "golang.org/x/crypto/bcrypt"
)

type User struct {
    ID       uint
    Name     string
    Email    string
    Password []byte
}

func (user *User) HashPassword(password []byte) {
    hashedPassword, _ := bcrypt.GenerateFromPassword(password, 12)
    user.Password = hashedPassword
}

func main() {
    r := gin.Default()

    r.GET("/user", func(c *gin.Context) {

        user := User{
            Name:     "test",
            Email:    "test@gmail.com",
            Password: []byte("password"),
        }

        user.HashPassword(user.Password)

        c.JSON(200, gin.H{
            "message": "done",
        })
    })

    r.Run(":5050")
}

I benchmark from Postman status: 200 OK Time: 800ms

Why this pkg take this time!?


Solution

  • That's the whole purpose of a key derivation function such as BCrypt is to be computationally expensive in order to make brute-forcing impractical.

    But the cost factor of 12 is too high. You should reduce it to 10 or 8.

    bcrypt.GenerateFromPassword(password, 10)  // 10 is the default cost
    

    Here's a demo timing test with different BCrypt cost factors:

    func test(cost int) {
        t1 := time.Now()
        _, _ = bcrypt.GenerateFromPassword([]byte("test pass"), cost)
        t2 := time.Now()
        fmt.Println(cost, ": ", t2.Sub(t1))
    }
    
    func main() {
        for i := 4; i < 15; i++ {
            test(i)
        }
    }
    

    Output:

    4 :  2.2077ms
    5 :  3.404ms
    6 :  6.8319ms
    7 :  14.732ms
    8 :  23.4149ms
    9 :  46.2739ms
    10 :  98.964ms
    11 :  187.7988ms
    12 :  371.6627ms
    13 :  754.1349ms
    14 :  1.5391565s