authentication – Is salt-free hash secure for random passwords?

I design an API with token authentication.

I do not want to store the tokens as plain text in the database, for the same reason, the users' passwords are not stored as plain text: if the database is compromised, the database will not be stored. attacker should not extract usable tokens.

My current plan is to generate tokens of 40 characters long, composed as follows:

  • the first 20 characters would be the "ID" token (the primary key in the database)
  • the next 20 characters would be the token "password"

When generating the token, I sent the full token to the client and stored in my database:

  • Token ID
  • a SHA1 hash of the token password

In this way, my database only contains half of the token sent to the client and can only check the tokens, not recover them.

I do not plan to add salt: As I understand it, the interest of salt is to prevent hash table / rainbow table attacks against commonly used or short passwords, whereas in my case the passwords are completely random, with enough entropy (67 possible characters, length of 4 characters = 4 × 1036 combinations). Unless I miss something, adding a salt in this case would be like creating a longer random password.

Also, I do not plan to use an expensive hash technique such as Bcryptthat would cost too much: unlike user authentication, where the user authenticates once then gets a session id, the token is the only authentication method used here and will be sent with each API call; a 50 ms hash method is simply not acceptable here. I do not consider that the use of an expensive hash technique is safer, for the same reason as previously discussed: the password is random with enough entropy. So even with a powerful hash machine, it would still take billions of years to be brutal.

Is there a flaw in my approach?

The only one I can think of (provided that someone has access to the database!), Is if a vulnerability is found in SHA1, so that it becomes possible to find an entry giving a hash given out (this happened to MD5, I heard). But I guess it's the same for all hash algorithms, including Bcrypt?