I have been reading a lot about QR codes and how the code itself can lead to serious security risks. But one thing that I did not come across is the following.
In th
Sign the QR code data with a private key. The readers will need the public key to verify the QR code, but the public key need not be kept secret.
If you use an ECDSA Secp256K1 key, the signature will only add about 68 bytes to the QR code data.
Include the date of issue in the QR code as well. The reader will need a local clock to check that the QR code isn't too old. If the reader doesn't have a clock, you can at least keep track of the newest valid code you have ever seen. Any code issued more than a year before that date is definitely invalid.
Both BouncyCastle and OpenSSL contain implementations of the code you'll need.
If it's okay for the code readers/verifiers to contain all the information needed to generate a fake QR code, then you can use HMAC instead of ECDSA. That's simpler and an HMAC can be as little as 16-bytes and still do the job.