1

We are in the making of an Android app, a quiz game, which we would like to cache questions + answers for when the user is offline. The problem with this is that we would need to withhold this data from the user until she has answered the questions. Otherwise, cheating would be very easy, which would harm the game. One could then extract all questions + answers and automatically submit answers to the server API.

The most convenient way would be to retrieve a key or secret from our server at installation time, hide it "somewhere", and use it for communication with the server, and also for the encryption of questions + answers in storage. But obviously, hiding it "somewhere" is not a secure concept.

I have researched a bit, and it seems that reliable encryption is not possible in such cases, because the app has to "know" the secret (be it a certificate, passphrase + salt, or whatever) or at least where it can be found, and this can be extracted by decompilation. However, we would be fine with it being hard enough to do.

The question is: Do you know of a way to make it prohibitively hard for regular users to retrieve a secret from the APK - i.e., make it near-impossible to write an automated key-extractor?

My best guesses so far:

  • Hide some information in the database and use it as salt for the key
  • Add several bits of information from the device as salt (IMEI, email address, serial number,...) - perhaps together with obfuscation the way how the salt is applied might be hard to obtain?
Bill the Lizard
  • 398,270
  • 210
  • 566
  • 880
manmal
  • 3,900
  • 2
  • 30
  • 42
  • What is the answer format? What's the penalty for wrong answers? Surely for anything multiple-choice it's pretty trivial. – tc. Jun 18 '11 at 17:35
  • Answers are either multiple-choice enumeration (1 to n correct choices), plain-text, numbers, or image coordinate ranges (puzzle picture) - perhaps there will even be more. Of course, we also apply algorithms that determine if an answer is correct - like levenshtein distance for plaintext answers. – manmal Jun 19 '11 at 10:42
  • 1
    For the multiple-choice questions, the best you can do is simple obfuscation; the user can always just try all of them in an emulator and restore from a snapshot on a wrong answer. – tc. Jun 19 '11 at 14:12
  • it is planned that questions' orders are randomized, and one quiz might not contain questions another does, so this is not as big as an issue. but thx, this is another attack vector we have missed up to now :) – manmal Jun 19 '11 at 15:15
  • 1
    Randomizing doesn't help if the user takes the snapshot immediately before answering the question. A different game design gets rid of the problem entirely (e.g. you can get as many wrong as you like, but you don't know if an answer is correct until the server tells you; it's not really a "quiz machine" style game anymore though). – tc. Jun 19 '11 at 15:20
  • Yes, our app will primarily be in syncronous-mode, but we also want users to be able to play without a connection (even for longer periods of time). Alas, providing no feedback on correctness is no option for this kind of game. Thx for your help, I think we will stick with a derivative of Graham Borland's idea, and live with the weakness of questions with few possible answers. – manmal Jun 20 '11 at 08:55

1 Answers1

1

You could use a separate key for each question, which depends on the answer to the previous question. So it's impossible to decrypt question 2 unless you've already answered question 1.

Graham Borland
  • 60,055
  • 21
  • 138
  • 179
  • Ah this is nice! We would like to avoid imposing a specific order on the questions, however we could live with that. Do you think it would also work without an encryption-chain, but that instead every question has a token encrypted with the correct answer? – manmal Jun 17 '11 at 16:31