2
$\begingroup$

I have to license a java application and want to code a quick implementation, the scheme I came up with is:

  1. The Application calculates a string X which we assume to be the md5 sum of the computer's mac address, the current date and some other information.

  2. the application returns a string Y equal to the last 16 digits of X to the user

  3. the user contacts the Software Support office giving Y and the office encrypts Y using AES with a secret key and returns a string Z equal to the last 16 digits of the encrypted Y

  4. the user inputs Z in the application and this checks that Z is equal to its own Z which is calculated the same way as at the Software Support. If the two are the same the software unlocks.

Now I would like to know whether two assumptions are reasonably safe or not:

  1. Assume a cracker knows how Y is calculated and can calculate it for its own copy of the software and uses this Y to request a Z to the support center and unlock his copy of the software. Is it possible he will be able to calculate for every possible Y he wants a matching Z to unlock any copy of my software?

  2. Because my software contains the encryption key inside the application bytecode a cracker with enough knowledge can decompile the encryption key and create his own Z to unlock the program (assume I tried my best obfuscating the code). A solution would be to use public key cryptography, however this would be useless in my opinion because if a cracker is able to decode the compiled bytecode of the application he will totally bypass whatever encryption scheme I will put because in the end there will always be a part of the code checking for a condition and setting that condition always to true will bypass any encryption scheme I will come up with. is it true?

$\endgroup$
5
  • 3
    $\begingroup$ If you use the standard AES API, then extracting the AES key is trivial. Just put some kind of breakpoint on the AES function. $\endgroup$ Commented Mar 5, 2013 at 13:04
  • $\begingroup$ I cannot understand your answer could you be more specific? what do you mean by breakpoint? are you answering A) or B) ? $\endgroup$
    – dendini
    Commented Mar 5, 2013 at 13:06
  • $\begingroup$ Running the application in a debugger will reveal enough information to calculate every possible key that will unlock your software. $\endgroup$ Commented Mar 5, 2013 at 13:40
  • $\begingroup$ so your answer to B is that my code is reasonably safe because whatever I will do a cracker running a debugger will be able to calculate whatever key I come up with. At this point I think he won't even calculate the key but simply change the code where it checks for the key to always validate whatever key!!! $\endgroup$
    – dendini
    Commented Mar 5, 2013 at 13:46
  • $\begingroup$ His answer to B appears to be that your code is completely unsafe, because a single attacker will be able to trivially build an application that allows any user to bypass your licensing. $\endgroup$ Commented Mar 5, 2013 at 23:32

2 Answers 2

2
$\begingroup$

To begin with, let's assume that the attacker cannot extract the AES key from your software. That means the best they can do is a chosen-plaintext attack on AES: choose a block $Y$, request its encryption $Z$, repeat as many times as desired and try to use the results to figure out something useful about the encryption of other plaintext blocks.

Since AES is believed to be IND-CPA secure, i.e. indistinguishable from a random permutation under chosen plaintext attacks, this is not likely to work. If the attacker cannot somehow distinguish AES from a random permutation (which, if AES is as secure as it's assumed to be, they shouldn't be able to do), all they can do is try to compile a long list of plaintext/ciphertext pairs and hope that the key they want to crack is found in the list. But as long as you don't truncate the inputs too much, that isn't likely to happen either. (You don't specify what you mean by a "digit", but as long as one digit contains at least 4 bits, 16 digits amounts to at least 64 bits, which should be sufficient.)


However, that's all assuming that the attacker cannot just extract the AES key from the software. If they can, then creating their own license key generator will be trivial. Note that, from the attacker's perspective, extracting the AES key is much more useful than just modifying the software to disable the key check: knowing the AES key allows them to create valid license keys for any copy of the software on any platform, including future upgrades.

Extracting the key is also likely to be easier than modifying the code, especially if you use the standard system crypto library for your AES implementation. (As CodesInChaos notes, the attacker can just run the code under a debugger and log all system library calls it makes; the call to AESEncrypt() or whatever ought to stand out as a good target for a breakpoint.) Using your own obfuscated AES implementation could make it a bit harder, but that's not really guaranteed to work either: crypto code tends to look fairly distinctive when decompiled, and even if the attacker fails to realize that they're looking at AES, they could still just lift the code and its inputs wholesale.

Thus, if you don't want anyone to be able to write key generators for your software, I'd strongly suggest using digital signatures instead. If you don't want to do that, your other option is to just obfuscate the heck out of your code and accept the fact that a skilled and determined attacker will be able to reverse engineer it and write a license key generator. Or, you know, consider whether you really even need a license key in the first place.

$\endgroup$
2
  • $\begingroup$ Your answer is very clear, I only miss the part on digital signatures: do you mean public key encryption (for instance RSA?), because in that case I would use a more advanced solution but in the end a skilled hacker would resort to modifying the code, so that's really just moving the problem one step ahead and failing in the same way (maybe now the cracker would have to distribute a cracked copy but in my perspective that doesn't change much). Am I missing something? $\endgroup$
    – dendini
    Commented Mar 5, 2013 at 15:31
  • $\begingroup$ Digital signatures are a form of public key cryptography (but they don't generally involve encryption, although some algorithms such as RSA can be used for both). Their advantage in your situation is that the software only needs to contain the public half of the keypair, which can be used to verify signatures but not to create new ones. Of course, distributing a modified copy is still possible, but considerably less convenient for the cracker than simply distributing keys to unmodified copies. $\endgroup$ Commented Mar 5, 2013 at 16:15
2
$\begingroup$
  • embedding a symmetrical (AES) key in your software really is pointless - an attacker could easily extract the key and generate their own software license key, or worse, create a small program (a crack) that allows other users to generate their own license keys
  • I recommend RSA - generate 'Z' (as per your question) by signing the data 'Y' with a private key, and verify 'Z' with the corresponding public key, which can be safely embedded in the application. The public key can only be used to verify the authenticity of data signed with the private key — it cannot be used to create a valid signature by itself.
  • Regarding someone decompiling your software, that's really not related to software licensing, but it's a valid concern, albeit not one that can be mitigated by cryptography. That being said, any 'cracker' skilled and determined enough to decompile your software and make their own version is probably skilled enough to write their own software anyway (generally speaking).
$\endgroup$
9
  • $\begingroup$ In my question in point B I already mention public key cryptography as well as retrieving the encryption key, so you're not really answering what I wanted to know. $\endgroup$
    – dendini
    Commented Mar 5, 2013 at 15:37
  • $\begingroup$ Let me answer your questions more explicitly: A) - Yes. B) Yes and no. No - using a public key sign/verify scheme is not useless. Yes - an attacker can decompile your app and do whatever they want with the code. $\endgroup$
    – hunter
    Commented Mar 5, 2013 at 15:55
  • $\begingroup$ I came to the conclusion the answer to A) Very unlikely (see IND-CPA secure talk by Ilmari). Regarding B) I'm still not seeing the advantage of RSA when the cracker can simply change the code checking for the key.. $\endgroup$
    – dendini
    Commented Mar 5, 2013 at 16:06
  • $\begingroup$ A) assumes that the license key can be decrypted and verified by the software, which logically requires that the AES key be embedded in the software. In this sense it ceases to be a 'secret' key, and thus, loses the confidentiality that secret-key cryptography provides. For this reason, using RSA would make much more sense. A) asks whether the attacker, for every instance of 'Y', can calculate 'Z'. The answer is yes, because obtaining the embedded secret key from the software is trivial, and not embedding the key would invalidate the scheme. $\endgroup$
    – hunter
    Commented Mar 5, 2013 at 16:28
  • $\begingroup$ A) asks whether the attacker for every instance of 'Y', can calculate 'Z' but without deciphering the embedded key (it's not explicitly written but that case is contemplated in case B) $\endgroup$
    – dendini
    Commented Mar 5, 2013 at 16:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.