I have a table for single use tokens, and one of the columns is a token_digest which contains a bcrypt hash of the access token. Since the token_digest is a salted and hashed version of the plaintext token, I can't just run a select against the computed hash.

When my application gets the plaintext token from a client, how can I find the correct token record from the database?

The only way I can think of solving this is by adding a prefix to the token that is stored in the database and isn't hashed. So you'd have something like prefix9581d7b867eb0fe0da59fc98faa27fb8. Then you can find the token in the database by issuing a select with where prefix = 'prefix'. Is this incorrect or an insecure solution?

1 Answer 1


I recommend that you take a step back and reconsider the use of bcrypt for your use case. brypt and similar functions are designed to address brute forcing of easy to remember passwords. They are deliberately designed to slow down an attacker so that brute forcing gets too costly.They also include a random salt so that precomputed hashes (rainbow tables) get infeasible.

But, an access token is different. There is no need to keep it short and easy to remember. Instead a long randomly generated key can be used. Such a key is resistant against brute forcing and precomputed hashes by design already, so there is no need to address any such weaknesses using a special hash function.

Instead it is sufficient to use a fast and unsalted hash function like SHA-2. This is even the recommended way: bcrypt needs much more computing resources compared to SHA-2 and an attacker might misuse this for a denial of service attack against the server.

And with a simple SHA-2 your problem suddenly vanishes: Simply compute the hash and look up the hashed value in the database. Since no random salt is involved the output of the hash is always the same for the same input.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .