6
$\begingroup$

So I'm making an Android application, I need my application to be only able to scan my own generated QR codes, and I want to make sure that nobody else can generate fake ones.

The data isn't sensitive, it's very okay to be read by anyone, and even be in plaintext.

The problem comes is that, I need to verify the source of the QR code, I've been suggested to digitally sign it, thus, I have my private key, and I ship my application with a public key, and the application then uses the public key to check the QR code

Some of the things I don't get:

  • Am I encrypting the whole message using the private key? or I just generate some separate signature that sits next to me message?
  • As far as I know, with RSA, for example, everytime I encrypt a message, a new private and public key are generated, right? So how is the application going to verify/decrypt the message if the public key is constantly changing per QR code?


Simply said:

My QR code data are something like:

{"a": 1, "b": 2, "c": 3}

And I want my application to make sure that this data comes from an authorized source, and not generated by anyone else.

$\endgroup$
13
$\begingroup$

I've been suggested to digitally sign it, thus, I have my private key, and I ship my application with a public key, and the application then uses the public key to check the QR code

As long as you can live with the requirements for RSA (signature size, computation), that sounds like an excellent idea.

Am I encrypting the whole message using the private key? or I just generate some separate signature that sits next to my message?

You're generating some separate signature that sits next to your message. That is, the RSA signature algorithm (which you run) takes the message (and the private key), and spits out a 'signature'. Then, the RSA verify algorithm (which runs on the phone) takes the message, the signature, and the RSA public key, and then outputs either "signature valid", or "invalid".

You would put into the QR code your message and the signature.

As far as I know, with RSA, for example, everytime I encrypt a message, a new private and public key are generated, right?

Nope. There are things known as 'one-time-signatures" where a public/private key can be used only once, but RSA isn't one of them. Instead, a single RSA private key can sign as many messages as you want.

$\endgroup$
  • 7
    $\begingroup$ In addition: you'll face the issue that an RSA signature has significant size in a QR-code context (e.g. 256 bytes or 342 characters with base64 encoding for 2048-bit RSA). You can reduce this with DSA or ECDSA (e.g. to 64 bytes), or with an RSA signature scheme with message recovery (e.g. to min(34, 256-m) bytes for an m-byte message with ISO/IEC 9796-2 scheme 3). And: the really hard part is to ensure that your application won't be modified by someone to suppress the signature check. $\endgroup$ – fgrieu Jul 21 '16 at 21:05
  • 1
    $\begingroup$ @fgrieu: This is why, ideally, you do the signature verification server-side, and then provide the application with whatever resource the QR code is supposed to unlock. $\endgroup$ – Kevin Jul 22 '16 at 3:23
  • 1
    $\begingroup$ It is usually not efficient to sign a whole message (ok, a QR code is not really that big), but the common practice is to create a hash and sign the hash. This is effectively what @fgrieu suggested. As an addition - you may add a timestamp and salt to the hash signed to limit options for replay attack (if someone would get a valid signature, he could resend it anytime). $\endgroup$ – gusto2 Jul 22 '16 at 8:28
  • $\begingroup$ @GabrielVince: I'm not exactly suggesting to hash the message and sign that, which yields a signature scheme with appendix. I'm suggesting a signature scheme with message recovery, which usually hashes the message, and embeds some of the message and the hash into the signature. Some of the message needs not be in the QR code (it's in the signature, and recovered as part of verifying that), thus the overhead of signing is reduced. For short messages, the whole message is embedded in the signature, and omitted from the QR code (total recovery). $\endgroup$ – fgrieu Jul 22 '16 at 11:15
4
$\begingroup$

To your questions:

  1. You are not encrypting anything. Signing something with RSA is basically the same algorithm as decryption but some things are different (see below).

  2. No. You can generate one keypair and then use it for encryption, decryption, signing and verification.

To help you with your task:

Getting this right is not easy. If you have no experience with it, get an expert to review your code. Otherwise, you will likely end up with more than one vulnerability in the QR scanning mechanism.

See this answer on how RSA signatures work. You should also use a cryptographic library instead of implementing anything your own (never roll your own crypto ;)). If you do that, you might as well use ECC signatures which are more state-of-the-art.

$\endgroup$

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.