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 the following scenario: I have a QR code which displays some of my data lets say: - Name - Address - A list of things I'm allowed to do
And I scans my code to see its contents, add some stuf to the list of things that I'm allowed to do and reprint the QR code. The next day I come to work scan my code and am allowed to do the extra thing I added to the code.
My question is: how can I stop this scenario from happening. Note that it is not possible to check if my data is consistent with DataBase data.
More info:
I'm using phonegap in combination with Sencha Touch 2 to create my QR code reader.
It is an Android application designed only for Android 4.0 devices.
The QR codes are provided once a year.
If someone would scan his QR code of last year it would not work.
Note that: in theory if he'd change the date on the code that he would be able to get in, this is exactly what I'm trying to block.
Some employees have access to the application which reads the code.
The application does not have any way to verify the data on the QR code, so it has to be something using only the data on the QR code.
This is all easier to reason about if you realize that QR codes simply encode plain text. If your scheme is insecure if you were just dealing in text files or text printed on a wall -- QR codes don't change that. There is no security mechanism in a QR code.
Turning it around -- whatever means are available to secure your scheme, outside of QR codes, can probably be applied here. What you are looking for is a digital signature, the same sort of public/private key scheme used to prove that SSL certs are valid and that emails are from the claimed sender. The data your users need to supply must be signed by you to know they haven't tampered with it.
You can put anything you want in a QR code, including Base-64 encoded bytes representing a signed document. No reader will know what to do with it; you'd have to write a custom app that scans and then knows to decode it and act accordingly.
I do think it's by far easier to conceive a scheme that involves directing a user to a web site you control securely.
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.
QR code is not more than encode a text into 2D image. So it is not QR code's responsibility to encrypt. But you can always generate a simple verification code, e.g. MD5 or Base64 that created from an unique id plus the date. Depends on what kind protection you want, you can either reject or disable the code comes with wrong verification code.
If you can't do any comparison, I don't know how you can secure. Maybe all information may be hashed with a secret key? then you can't reprint your code without the key