I have a customer with an existing ticketing system that generates tickets for events like theaters, movies, football and so on.
The information in each ticket is encoded in a 16 decimal digit numeric string. The information contains fixed positions for event date, event identifier, seat row, seat number and so on. This system has a numeric barcode on each ticket with room for 20 decimal digits. (https://en.wikipedia.org/wiki/Interleaved_2_of_5)
The main problem is that it is too easy for adversaries to generate false tickets with valid barcodes.
My customer now wants to encrypt the information in the barcode to make it more difficult to generate false tickets.
The requirements are as follows:
- The plaintext is a 16 decimal digit (0-9) string.
- The ciphertext is a 20 decimal digit (0-9) string.
- Consecutive ticket numbers might differ only in a single digit position in the cleartext, the ciphertext for consecutive tickets must still be completely different.
- It should be impossible to calculate the encryption key even if you have access to many valid tickets.
- The encryption key is the same for all tickets for a certain event.
- It must be difficult for an adversary to generate a valid ticket number, especially for a specific event.
- Barcode readers used for validating tickets should work completely offline - it is not possible to have a complete database of valid ticket numbers available to the barcode readers.
- Note that the 20-digit encrypted barcode after decryption must contain the full 16-digit plaintext. This means that we only have room for a 4-digit hash.
What kind of encryption and authentication should we use in this case? As I see it, the main problem is that the space in the barcode is very limited, so we can not use a real HMAC.