1
$\begingroup$

Hi illuminated crowd of cryptography.

I am currently working on a login token for a web API.

The feature for the token is to be a mostly featureless identifier. The only property I need is, that I should be able to distinguish it from a random number before I query my database if it is actually valid.

I also don't want the token to be large.

This is what I came up with.

  • Receive a Username/Password, validate against database, collect user-properties. This can be rather expensive.
  • Generate a login token to be used for subsequent calls of the user, until the token expires, timeout is not part of the token.
    • create a UUID
    • Encrypt it with AES-128 using a server key plus a user specific IV
    • SHA-1 the original UUID (fake SHA won't matter)
    • append the encrypted payload to the hash
    • encrypt again to generate the token
  • write the token with the user-object to a memory-hash-db

To test the validity of the token, I decrypt the token. Then decompose the token into hash and encrypted payload. Decrypt the UUID, hash it and compare to given in token. If they match, try the lookup in the db.

This is a lot of calculation and hashing. I suppose it is rather fast, yet, the token is only valid for about 10 minutes (at max). Is it worth the effort? Doing a DB lookup may be faster for the in-memory cache.

So, an alternative would be to simply create a random number, big enough, and store it into the cache-database and lookup the token every time. Given the characteristics of UUIDs, an attacker should have a hard time to guess a token currently valid in the database.

Content encryption is established and MITM attacks are avoided using HTTPS.

What is your experience with this situation - is cryptography improving security in this case? What is a good algorithm to create such a token?

UPDATE:

After reading about AES-GMAC and AES-GCM as suggested in the comments, I decided to drop my original idea and use GMAC instead. It offers some nice features:

  • it is proven
  • it is approved by NIST
  • it is standardised, I already have a token-generator build in no time.
  • I can easily expand the token with encrypted information, if required.
  • tokens are acceptable in length (<100char BASE64)

My original question has been answered by giving me the hint to use a MAC on the token instead of cryptography. With AES-GMAC I get both, just in case :-)

Not using a MAC or crypto would make an attack with guessed tokens very easy. The MAC protection makes this very hard to hit.

Thanks for your help!

$\endgroup$
  • $\begingroup$ Does each layer of encryption use a unique key and IV? $\endgroup$ – Q-Club Mar 17 '17 at 2:27
  • $\begingroup$ Currently no. I added the second encryption to remove the possibility to test decryption with the hash. $\endgroup$ – thst Mar 17 '17 at 4:48
  • $\begingroup$ @back_seat_driver as payload is a uuid, the ciphertext will never be the same. $\endgroup$ – thst Mar 17 '17 at 5:19
  • 1
    $\begingroup$ Instead of rolling your own encryption scheme, couldn't you just use AES-GCM? $\endgroup$ – SEJPM Mar 17 '17 at 8:18
  • $\begingroup$ I will have a look. $\endgroup$ – thst Mar 17 '17 at 8:42
2
$\begingroup$

For a featureless identifier a simple random number + MAC thereof should work.

You don't actually need encryption because your number doesn't contain any sensitive information and checking the MAC allows you to verify that this is actually a token that you generated.

This requires only a symmetric key for MACing on the server.

$\endgroup$
  • $\begingroup$ Thanks to your and @SEJPM input, I will use AES-GMAC to generate the token. $\endgroup$ – thst Mar 17 '17 at 11:31
  • $\begingroup$ you can even use incremental number, append with its HMAC and use as token? $\endgroup$ – khan Mar 17 '17 at 12:28

Your Answer

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

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