1

I'm trying to learn how digitally signing a licence file helps prevent piracy. For example say an application only runs if it verifies the date as specified in a licence file has not past. Obviously it would be easy for someone just to change the date in the licence file, so to prevent this the licence file contains a digital signature of itself (i.e. the real expiry date) that was made using

KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
kpg.initialize(512);
KeyPair keyPair = kpg.genKeyPair();

byte[] data = expiryDate.getBytes("UTF8");//expiryDate is the string containing expiry date

 Signature sig = Signature.getInstance("MD5WithRSA");

 sig.initSign(keyPair.getPrivate());
 sig.update(data);
 byte[] signatureBytes = sig.sign();
 try {
            appendSig(licenceFileName, new BASE64Encoder().encode(signatureBytes));//append signature to licence file

After the licence is made like this, the actual application would have the public key to decrypt the signature and verify that the plaintext version in the licence file matches.

    String inSig=input.nextLine();                        
    Signature sig = Signature.getInstance("MD5WithRSA");


    sig.initVerify(pk);
    sig.update(expiry.getBytes("UTF8"));

    //this should be true  
    System.out.println(sig.verify(Base64.decodeBase64(inSig.getBytes("UTF-8"))));

Is this right? The decodeBase64 won't compile and says "cannot find symbol". I'm sure if I were doing this right the standard Java library would support it.

Am I at all on the right track? I'm assuming the licence file is a plain text file.

5
  • I'm not sure to get what is your exact issue or question. The license file is signed by the software editor. When generating the license file, the editor calculates a hash over the license information data and encrypt it using its private key. When starting, the software calculates the very same hash, then decrypts the signature using the editor's public key and ensure that the calculated hash matches the decrypted one. Sep 22, 2015 at 9:50
  • "The license file is signed by the software editor. " Where exactly is this signature stored? For example if the license file was a text file, would the signature be appended on to the end of it?
    – Celeritas
    Sep 22, 2015 at 10:24
  • I suggest you read this: en.wikipedia.org/wiki/Digital_signature Sep 22, 2015 at 10:57
  • @Celeritas (do not forget to mention the user with the '@' so he gets notified of your answers ;) ), the location of the signature is completely up to the software designer. It might be at the end of the file, for instance a text file where it will be the last line and the hash calculated with the n-1 lines, or it may be a XML file, or the license may be in one file and the signature in another (less practical, but some software use this), etc. Sep 22, 2015 at 11:39
  • To verify a digital signature, the application needs a public key of the license signer. Someone trying to use the program without your permission only have to modify the public key stored in the application code, so it uses their own public key, and then they would be able to create a license for themselves.
    – Lie Ryan
    Sep 22, 2015 at 12:38

2 Answers 2

6

Let's state things clearly: there is such a thing called asymmetric encryption. There is another, completely different thing called digital signatures. Whenever you see some text that talks about "decryption with the public key", then that text is really talking about signatures, and is trying to explain signatures as if it was some kind of encryption, which:

  1. works only for a specific algorithm called RSA;
  2. does not a actually work for RSA, when looked at closely.

So it is much better to talk to things under their true names.

What a signature can do for a license file is to guarantee that a piece of data is genuine:

  • The vendor owns a key pair that consists in elements that are mathematically linked together: the public key and the private key. They are called that way because though they are facets of the same mathematical object, there is no known method to rebuild the private key from the public key; thus, the public key can be made public, since this does not reveal the private key.

  • The vendor uses the private key to compute a signature on the license file. The signature generation algorithm uses as inputs the data to be signed (license file contents) and the private key, and outputs the signature.

  • The application verifies that the signature is correct. The application can do that because it embeds a copy of the vendor's public key: the signature verification algorithm uses as inputs the data which was signed (the license file contents), the public key, and the signature; and that algorithm returns "that's OK" when the three elements match.

    By the magic of the cryptography in the signature algorithm, only the private key owner (the vendor) can produce signature values that the verification algorithm will accept as "correct" with regards to the vendor's public key. Outsider, who do not know the private key, cannot do that.

It is still up to the application to enforce whatever the license file says. What the signature on the license file guarantees is that the license file really comes from the vendor. The rest is up to the application.


Of course, signed license files do not really prevent piracy. The critical part, here, is that the application must still include a copy of the vendor's public key, verify the signature, and apply the rules contained in the license file. Someone who wants to copy the application and run it elsewhere may still do a bit of reverse engineering and do one of the following:

  • Replace the public key embedded in the application with his own public key, for which he has the corresponding private key, allowing him to produce his own fake license files that the application will blindly accept.

  • Patch the application code that checks the signature on the license file so that an invalid signature is accepted nonetheless. This is not hard to do; ultimately, in the compiled code, there is a conditional jump opcode that sees what the signature verification algorithm returned (a boolean value that says "signature is valid" or "signature is not valid") and jumps to the relevant piece of code. It suffices to replace that conditional jump with either a nop, or an unconditional jump.

  • Remove the whole license file processing code altogether. Wherever the application contains a call to the license-checking system, simply remove the call.

Since that kind of reverse engineering is easy, it would be wrong to imagine that a signed license file really prevents software piracy. What it helps with, though, is legal qualification. When some reverse engineering is involved, intent is made plain. The software pirate can no longer be casual about it; by altering the application code to circumvent the license file checks, he clearly demonstrates that he knows what he is doing. Depending on the jurisdiction, such a legal qualification can matter a lot when it comes to police raids and trials.


Your code appears to create a 512-bit RSA key, which is very weak. A 512-bit RSA key was cracked in 1999, with the computing power that was available to academics at that time (by "cracking" I mean "reconstructing the private key from the public key"). Nowadays, it can be done with a single desktop computers in a couple of months; alternatively, it can be done in a few days with about 75$ of rented computing power from some cloud vendor like Amazon.

Similarly, using MD5 as companion hash function (the RSA signature algorithm uses a hash function as additional element) will get you bad points, since that function is considered "broken" (actually, it can still be used securely in the context of RSA signatures, but one has to be careful about it, and it still looks bad during audits).

You seem to sign just the "expiry date", which makes your license files generic -- applicable to all application instances. This is problematic because it suffices of a single leak of a valid license file to allow everybody to use it. Usually, people who make signed license file design the file contents so that the signed data includes a unique identifier for the application instance: the application, when it installs on the computer, create a unique, random identifier, sends that to the vendor, and the vendor signs a license file that contains that identifier. That way, a license file can be made specific to each instance, and not usable to unlock any other instance. Alternatively (or complementarily), the license file may contain the customer name so that leakages can be traced back to the culprit (and thus, hopefully, deter wannabe leakers).

0

A digital signature scheme typically consists of three algorithms;

  1. A key generation algorithm that selects a private key uniformly at random from a set of possible private keys. The algorithm outputs the private key and a corresponding public key.
  2. A signing algorithm that, given a message and a private key, produces a signature.
  3. A signature verifying algorithm that, given the message, public key and signature, either accepts or rejects the message's claim to authenticity.

Two main properties are required. First, the authenticity of a signature generated from a fixed message and fixed private key can be verified by using the corresponding public key. Secondly, it should be computationally infeasible to generate a valid signature for a party without knowing that party's private key. A digital signature is an authentication mechanism that enables the creator of the message to attach a code that acts as a signature.

Source: Digital signature - Wikipedia

In your case, the developer signs the expiry date with his private key to produce a signature with which the license file is signed.

The application will use the file, developer's public key and the signature to verify the license file's authenticity. If you tamper with the file, this verification fails.

1
  • The public key is built in (i.e. hardcoded) into the application, right?
    – Celeritas
    Sep 23, 2015 at 7:10

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .