3

NOTE: I know that there are numerous topics here on StackExchange about this but I've read them all and this question still persists.

I'm currently working to enhance the security of a windows based application that is sent to specific clients. We use AES encryption to create a big binary file with license data. In this data we have numerous hardware restrictions and things like user name and login. AES keys are stored within the application in a very secure and complicated manner and accessing the keys is done by a "random-based" routine that never uses the same key twice.

So far so good but new policies demand that everything should be signed by an asymmetric encryption scheme. I've being studding RSA and I can totally see how it works for most cases, but in this scenario there's a tiny thing that I still get into my head:

Most posts say that you should sign your license file and send it along with the public key so that it could be verified. So the software doesn't know the privet key, it only has a public key to check the license hash.

Question: What is preventing the user to just sign the license with his key and use his public key to verify it: How does the software can guarantee that the license is in fact made by me and no someone else?

Is more of an conceptual question because is really not clear how this signing will add security at all.

On symmetric encryption the software is build in with information that can decrypt and verify a license. But if the software is depending only on a public key, how does that work?

Thank you all in advance for you time

AleksanderCH
  • 6,511
  • 10
  • 31
  • 64
trosolens
  • 31
  • 2

1 Answers1

3

keys are stored within the application in a very secure and complicated manner

Secure and complicated are antagonist, except when it comes to security by obscurity. But, the later is the only practical way to implement "software licensing" (the politically correct term for copy protection) on modern computers without using some sort of trusted hardware or enclave (which this answer does not consider).

you should sign your license file and send it along with the public key so that it could be verified.

That's insecure, as noted in the question: there's noting cryptographic to prevent an attacker from generating a fresh public/private key pair, using that private key to sign an unauthorized license file, and send the signed unauthorized license file with the fresh public key.

The baseline sound way is that the code implementing the license verification, and specifically the signature check, contains (or comes with) the publisher's public key, and it is assumed¹ attackers can not change that public key, no more than they can change the code to bypass all license verification.

There is one significant advantage to thus using signature: it gives strong cryptographic insurance that no amount of reverse-engineering will allow an attacker to generate new license files that will get accepted by unmodified genuine software. That's not possible with symmetric cryptography. It's not a silver bullet, though:

  • Attackers can and do modify software.
  • Legit license files could still be accepted in multiple identical virtual machines if they reproduce the authorized machine faithfully enough.

No cryptographic protection from the above two threats is obtained by adding bells and whistles like:

  • Key identifiers, with multiple public keys in the software, allowing key rotation and independent issuers.
  • Hierarchy of keys (PKI). With this, the license file could indeed come with a public key, with that key itself signed together with its metadata (the technical term is certified) by the publisher's public key(s), soving the question's security problem.
  • X.509 certificates
  • Revocation server

¹ This assumption must rely on some level of code obscurity. Among standard techniques:

  • Code tries to check that it was not modified, thru OS services (e.g. Authenticode² on Windows as pointed by SEJPM) or/and self-checks.
  • The public key is stored encrypted, and is deciphered and checked by the security code before use, using symmetric cryptography with a key in the security code. This mitigate attacks that work by altering the public key.
  • Some of the above keys are hidden among other material with similar redundancy, to foil attacks that locate keys based e.g. on the distribution of the bytes they contain.
  • If the masters of the executable platforms have no binding rules against it, reverse-engineering is complicated by having the security code
    • Processed by code obfuscators.
    • Stored encrypted, and deciphered before execution.
    • Compiled to pesudo-code for an interpreter, perhaps custom.
fgrieu
  • 149,326
  • 13
  • 324
  • 622