I am building a web API and I have a hard time choosing between cryptographic session token and stored random session token for user authentication.

I see several pros & cons for each:

  • stored random session token (store an expiring pair {token:userId} in a db):

    • really random, with a negligible collision risk; an additional unique check can be done during database insertion
    • stored in a database, which leads to scaling costs, devops maintenance costs
    • tokens can be revoked
    • no risk of cryptanalysis as long as the correct random function is used
  • cryptographic session token (use an strongly encrypted mix of 'userId, expiryTime' with a common symmetric key stored in the backend)

    • random at each session, thanks to expiry time & a nonce
    • no need to store them (no need for extra network calls) - symmetric decryption of session token will be faster. This leads to massive devops improvement and cost
    • tokens cannot be revoked
    • risk of cryptanalysis
    • negligible but existing collision risk that cannot be prevented
    • risk with the symmetric master key

The safer approach seems the stored random session token, however the costs & devops database related issues are really making me doubt.

Any help on the best practice, and whether the cryptographic session token would be considered bullet proof by security experts? Perhaps a suggestion of a stronger solution?

The provided link still acknowledges that both are used - I am wondering if a security expert will reject the crypto token for a banking website? Where do you draw the line?

marked as duplicate by paj28, user45139, WhiteWinterWolf, Lucas Kauffman, Rоry McCune Sep 22 '15 at 21:12

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

  • 1
    Banking apps almost universally use a database token – paj28 Sep 20 '15 at 18:43
  • 1
    You may like Macaroons: hackingdistributed.com/2014/05/16/… - just make them time limited and link critical authorizations to locally stored individual keys which you can edit in order to revoke the authorizations (as that breaks the HMAC verification). No practical collision or cryptanalysis risk. – Natanael Sep 21 '15 at 10:36

Speaking as a security consultant, yes, I would absolutely flag the second approach as a security vulnerability. A key like that is at far too much risk of an attacker finding some way to dump or otherwise determine it, and once they do that they can impersonate any user. You could make it harder through a number of tricks, but at the end of the day you're trusting the client to do session management. Don't do that, even when the info is supposed to be opaque to the client. If nothing else, the revocation is itself a good point (especially if your tokens have non-trivial lifetime).

Caching small pieces of data, like a session ID -> user ID mapping, can be done pretty easily and with minimal overhead. Adding new mappings is relatively uncommon - each session will be used many times for each time one is created - so you don't have to optimize for creation. It doesn't necessarily need to be persisted to anything; for a banking website your tokens should be very short-lived! As for "doing it right", a token of safe length (128 bits is good) from a cryptographically secure random number generator makes an excellent ID token.

Not the answer you're looking for? Browse other questions tagged or ask your own question.