I have an API that is handling a lot of volume and is using Basic authorization. This is causing me some performance issues and I'd like to move to token based auth but for various reasons, including problems forcing integrated parties to migrate to a new API version, I am unable to do so.

So, for the time being I'm stuck running Basic authorization on each request. Because I use bcrypt this takes a considerable amount of time (on average 70ms out of 350ms total response time). I understand that this is the correct way to hash passwords from a security standpoint so this is definitely something I want to keep but at the same time I'd like to optimize this so that I don't have to pay this 70ms penalty on my response times.

What I have so far is that I'd compute a SHA512 of the credentials combined with 2 peppers, use this as a cache key and check it for a record. If there's no record under the given hash then I would run the bcrypt authentication code and if successful save the result in the cache with 15 mins expiry. This way I'd save a considerable chunk of the response time when creds are valid and cached but force all invalid requests into bcrypt.

There are some issues around password resets/changes but they are not a huge deal and I have a solution for them. What I'm wondering is what are potential issues to this approach, especially from a security standpoint? If a malicious party was to obtain some of these hash values from my cache how hard would it be to bruteforce the credentials, assuming they cannot access the peppers?

  • Why don't you just make the change backwards compatible? Your system checks for token-based auth and uses it if present, but if not falls back on basic authentication? – Conor Mancone Oct 26 '20 at 13:58
  • @ConorMancone yes, that is an option and I will still implement it. The issue is that the vast majority of my volume is coming from a few major clients that will not be able to change their implementations any time soon. The performance benefits of having token auth will not be felt as 90% of volume will go through the old auth flow. – user244760 Oct 26 '20 at 18:27
  • What is actually being sent via basic auth? An actual username and password? Or a token? Some may disagree with me - although they would be wrong :) - but password hashing is mainly meant as way to protect users against their own bad password policies. The same level of protection is not needed for an strong and random API key as is needed for a self-generated user's password. You said this is an API, so it stands to reason that these are API keys. You don't bcrypt for an API key. Heck, you may not even need hashing. – Conor Mancone Oct 26 '20 at 19:00
  • @ConorMancone unfortunately these are user generated credentials i.e. username and password. I would assume these clients have generated strong passwords but I cannot be certain. So you're saying that if API keys are randomly generated there's no need to protect them with a hash even if a malicious party obtains a db dump because it will be cryptographically too much work to find a match? In that case, would you say that having a strong randomly generated secret as pepper in my hashing approach is good protection for the user creds in my case? – user244760 Oct 27 '20 at 12:18
  • It really depends. The trouble is that API tokens and passwords have very different use cases. In the case of an API token you need to tell the user what their API token is, so oftentimes they are simply stored as plain text. However some systems generate one and then "forgets" it, so in those cases they are likely stored hashed (although a simple SHA256 is probably sufficient). The thing to keep in mind is that API tokens are meant to be rotated anyway, so, in a sense, a lost token is less "risky" because it is easy to change. Getting users to change passwords well is hard. – Conor Mancone Oct 27 '20 at 12:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.