While you're likely in serious trouble if someone gets your DB this helps minimize damage. Besides to authenticate a request you dont need the plaintext of the key, a hash is fine.
While you're likely in serious trouble if someone gets your DB this helps minimize damage. Besides to authenticate a request you dont need the plaintext of the key, a hash is fine.
I guess the trade-off is here that the api key cannot then be retrieved from a GUI either (because the server doesn't actually know the original key!) .. from a UX perspective, most companies show your active keys in a GUI with ability to selectively remove or replace.
Though I can't think of a mainstream API that hasn't let me retrieve api key from GUI
Ideally you'd regenerate the key each time the user wants to show it or just use OAuth 2.0 (it's not as bad as everyone says it is).
You cannot brute force search against a large random number that is hashed with unsalted SHA or the like. This would require you to guess the number, hash it and check to see if the hashes match. A large random number encoded as a 64 character string is simply too big to guess, even at millions of guesses per second.
Thus using bcrypt to protect your api keys does nothing but impose a serious bottleneck in how many api requests per second you may authenticate.
It doesn't matter how many machines you have or how fast you can compute the SHA. An attacker will not find the API key (work out the math).
The reason you need bcrypt is that user supplied passwords are crap, and can be cracked very quickly.
EDIT: To make it clearer: "Long" is not explicit. 256 bits is. The difference between real randomness and for example output of RND in your favourite language is also nowhere to be seen. Moreover the use of the "key" is dubious as it's not an encryption key at all.
"Only use the users password to obtain a long random key" (emphasis mine).
So it was part of the initial recipe.