4

I'm trying to find a good algorithm for generating authorization codes, access tokens and refresh tokens in an API.

Currently, I am looking into the following setup:

Tokens are generated using the RNGCryptoServiceProvider class in C#. (I have limited the allowed chars to the following set: abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNOPQRSTUVWXYZ0123456789!@$?_-)

Authorization codes are generated with 256-bit length and have a lifetime of 5 minutes. Access tokens are generated with 512-bit length and have a lifetime of 1 hour. Refresh tokens are generated with 2048-bit length and have a lifetime of 60 days.

Those codes and tokens are then salted with a random 64-bit salt, and then hashed using SHA-256 before being stored in the database.

Considering the token lifetime, salt and hashing algorithm used, would this be a reasonable secure setup?

azzlack
  • 143
  • 1
  • 5

2 Answers2

2

Your setup is secure. However it is largely "unneccessarily" secure.

First the generation method: You're using the RNG-CSP which is (I guess) Microsoft's software interface to the Windows secure PRNG, so this is fine.

Now for your tokens:
You're restricting the character set, which reduces the possible entropy per byte, but is fine if you're in a Web-Context. Note that you "only" have about 6 bits of entropy per byte (8 bits).
Your tokens are however too large. The standard security levels are 128, 192 and 256 bit security with 256 being considered secure as long as we're stuck in our solar system and don't discover any fancy energy source except our sun. Your current token sizes provide 192, 384 and 1536 bit security which is unneccessarily large in the latter two cases. I'd suggest changing the token's lengths to 384 bit. If you want, you can keep your short-time tokens at 256 bit or you can also raise the size if you feel 192-bit security (secure for a few decades at least) isn't enough.

Your choice of the hash is fine, SHA-256 provides 256 bit pre-image resistance which is just what you seem to want. Larger hash functions may be an option for you if you want to have more than 128-bit security against quantum computers, which would require you to use SHA(-3)-512

TL;DR: The long tokens may be shortened to 384 / 256 bit length, the rest is fine.

SEJPM
  • 46,697
  • 9
  • 103
  • 214
1

While SEJPM answered your question quite directly, please consider using stateless tokens instead. A token would be of the form identity_data||expiration_date, encrypted and authenticated using AES-GCM or perhaps ChaCha20-Poly1305. Your token is the nonce and cipher text concatenated and base64 encoded. Such a scheme prevents you from having to make a database query on every request, and prevents having to worry about replicating your session store database for high availability. All you need to do is distribute the key used for this token encryption to each server. The clients themselves act as your "token database", and your architecture is vastly simplified.

rmalayter
  • 2,297
  • 17
  • 24