# Algorithm for generating OAuth tokens

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?

-
You don't need to go beyond the 256-bit length. 256-bit length is already considered secure for centuries. – SEJPM Oct 29 '15 at 12:18
Do you mean using SHA-256 is enough, or the random token is enough with 256 bit length? (Or both?) :-) Can I drop the salting since the token is random anyway? – azzlack Oct 29 '15 at 12:38
SHA-256 is OK, the tokens may be increased to 384-bit in size (considering you only have 6 bits of entropy per byte) anything beyond is pure overkill (even 256-bit length would be OK with 192-bit security). And you don't need to salt as your strings are high-entropy and salting is the counter-measure to fast low-entropy guessing. – SEJPM Oct 29 '15 at 12:45
@SEJPM Looks like you’ve got yourself an answer there. (Just saying…) – e-sushi Oct 29 '15 at 16:11
Completely agree, but how do I mark a comment as answer? – azzlack Oct 29 '15 at 16:19

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.

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.