I want to generate a link that will be given to a user. On this link, as a parameter, I will add a token that will be valid only for a few days. So after that time, the server will check the token, see that it's not valid anymore, and disallow the download.

What I would like to do is create a token that doesn't require any server side state, i.e. that doesn't require me to create a table with the token/expiration date association.

I'm wondering is there any clever algorithm that would allow me to do that? Basically a token that cannot be decrypted after a given time (assuming that the decryption algorithm on the server is using the real, current, time).

  • 5
    Why not simply hand the client an encrypted token containing download reference and expiration? When the server receives the token, it decrypts it, notices the expiration has passed, and declines to allow the download. Because reference and expiration are both encrypted, the client can't tamper with them. The only thing the server needs is the key used to encrypt/decrypt the tokens. – gowenfawr Apr 11 '17 at 13:04
  • What if users who get the link share it with others? Would that cause a problem for you? – Limit Apr 11 '17 at 16:37
  • 1
    Alternative to encryption, is cryptographically sign the data. – ctrl-alt-delor Apr 11 '17 at 19:54

So after that time, the server will check the token, see that it's not valid anymore, and disallow the download

Yes, just package up some data identifying the asset to be downloaded with an expiry date and encrypt it using an appropriate algorithm (if the issuer of the token is also the validator, then a symmetric algorithm is OK, if they are separate bodies, then encrypt with a private key on the issuer and decrypt with the corresponding public key on the validator.

The issuer and validator need to store the keys.

The validator must also control access to the downloadable file.

Do make sure that you create an appropriate representation of the (encypted) token that will will easily ass through the mail system and is valid in a URL.

That's around 10 lines of (PHP) code for the issuer and 20 or so for the validator.

a token that cannot be decrypted after a given time

No, that's impossible.

| improve this answer | |

You could use an encrypted token consisting on a prime number and an expiration date. For encrypting the token just use a symmetric algorithm such as AES.

You would need to keep track of

  • The difference between the number of tokens generated and the number of tokens validated, d
  • The last prime number generated, p
  • The product of all primes generated, t

To generate a token

  • Increase d
  • Calculate the next prime p and return that (this can be done efficiently).

To validate a token

  • Check that the token has not expired
  • Check that t is not divisible by the prime number

If the token validates

  • Multiply t by that prime number
  • Decrease d

This way, you automatically invalidate the token so it cannot be used anymore (next time you try to validate that prime, t will be divisible by it so it will return false).

Every time the number of tokens validated equals the number of tokens generated (d=0), you can also reinitialize all the variables (p=1,t=1) so that the size of t does not grow indefinitely.

| improve this answer | |
  • "d" will never go down to 0 in practice. Also, this schema is overly complicated, I do not understand why you need a prime number: you already use an encrypted timestamp in you proposed solution. – A. Hersean Apr 12 '17 at 14:25

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.