Home > OS >  Go x/crypto/bcrypt: Using a custom salt when generating the password hash
Go x/crypto/bcrypt: Using a custom salt when generating the password hash

Time:07-02

I am trying to implement a basic authentication system for a Go server that consists of users with multiple server-generated passwords (tokens essentially) which must be securely stored in a database.

One way of accomplishing this would be to hash the passwords with a one-way function and a globally unique salt.

However, since users have multiple passwords in my case, this creates a problem for authentication; each of the user's passwords would likely have a different salt, so the server would need to iterate through the passwords in the database, hash the supplied password using the same salt as the one in the database, and then compare. This does not seem efficient.

Alternatively, I was thinking that I could relax the "globally unique" constraint on the salt and randomly generate a salt when the user is created, and use it for all that user's passwords. With this, I would only need to hash the user-supplied password once, and could then use an SQL query to perform authentication. This is also the solution suggested in this related question.

However, the Go x/crypto/bcrypt package does not expose a function which hashes passwords with a custom salt, its salt generation is private. Is this for a good reason? Are there vulnerabilities with this approach of using a common salt for all of a user's passwords?

This problem seems common enough given that sites like GitHub and GitLab would have to deal with it for their personal access token storage, yet it appears that GitLab (by default) simply performs a sha256 hashing on their generated tokens.

CodePudding user response:

By design each hash would have it's own salt, this is stored in the database. as a string with the salt, password hash, bcrypt passes etc. It appears all or most newer gen cryptography does this so each hash would have to be cracked individually. If you want something stored in your code I'd add a pepper to every password and then let their salts be unique in the db.

You're worried about efficiency of iterating over each password but I wouldn't be, security is probably better than your login efficiency. Just store their login session for x days?

Are there vulnerabilities

Well yes, bcrypt itself is considered vulnerable if that's an answer?

I think you should go with argon2id since it is what is considered "good" today, and since your program is new https://pkg.go.dev/golang.org/x/crypto/argon2 This is a wrapper so it is safe as far as the Go crypto is concerned, and very easy to use: https://github.com/alexedwards/argon2id

If you're wanting tokens you should probably use UUIDs

  • Related