Suppose that I want to give to users of my site the option to pay for a service and use it later.

I am thinking to generate a unique ID for the paid service. I want to be able to trust the ID to decide if the user has paid the service or not but I do not want to store anything on the servers because the ID should have all the information that I need.

How long should the ID be to ensure that nobody would be able to forge one without paying ?

Are there best practices to generate this ID ?

Do you think that it would be possible to store the ID on a QR? It seems that the QR becomes too big when you try to store, for example, 1024 characters.

  • I'm unclear on what you're asking. Who shouldn't be able to forge an ID? Someone who has seen one and would like another ? Why wouldn't they just reuse the one they've seen ? Or would you like to prevent someone who's never seen an ID from guessing one ? Feb 11, 2017 at 16:31
  • Good point. I forgot to say that in my case it does not make sense to buy the same service twice. Feb 11, 2017 at 17:32
  • So you'd just like someone not be able to guess an ID without ever having seen one? Feb 11, 2017 at 17:33
  • It shouldn't be able to guess a new ID even if he/she has received one. It does not make sense to reuse one already used because it won't have any effect. Feb 11, 2017 at 17:42

1 Answer 1


There are two possibilities :

  1. You only need to make sure your server generated the token

The simplest way I see is to make the token you give the user a concatenation of the ID (which could be a simple incremental ID) and an HMAC of this ID. Given an HMAC key of an appropriate length (at least 128 bits), the user wouldn't be able to generate a valid token.

The HMAC length itself depends on the algorithm you choose. Encoded in base64, an HMAC-SHA1 takes 28 characters, an HMAC-SHA256 takes 44 characters. That leaves you with quite some space for your ID even if you encode the token in a QR code.

  1. You also don't want the user to know the token's content

I would suggest encrypting the token's content using authenticated encryption. You could use AES-GCM or AES-EAX for example. Using a key of a sufficient length, the user would not be able to know the token's content nor be able to modify it without your server noticing.

This will add some slight overhead to the data, but I'm not as familiar with the algorithms. I'd estimate about 50-100 bytes once base64 encoded, which still leaves quite some space for your data in a QR code.

  • Ok. It makes sense. Feb 11, 2017 at 18:34
  • Actually, I was thinking to make the information in the QR not readable. I do not like that someone can somehow get the QR and read what the user bought. If I use your solution, I wouldn't be able to hide the information because I need it to check the hash. Feb 11, 2017 at 18:43
  • I've modified my answer to cover your comment. Feb 11, 2017 at 20:14

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.