Securely storing AES key in application binary

At work, i am developing an application in C++ that should be protected by a license file.

I am using AES 256 in CBC mode to generate the licence file using a fixed key and a random IV vector each time.

The IV is prepended to the licence file so i can read it later and feed the decrypt method with it.
The key is hardcoded in both the licence generator and the application.

My question is if it is possible to retrieve the key from the binary by decompiling or similar techniques and how can i prevent such action?
 
Why not use public key cryptography to sign and validate the license?
That's a good question.

Answer is that it's kind of a standard in the company i work at to use AES for license files. Thought it was easier to do it the same way.

Thinking about changing it to public key cryptography.

Thanks for the hint!
 
Answer is that it's kind of a standard in the company i work at to use AES for license files. Thought it was easier to do it the same way.
if all you have is a hammer, everything looks like a nail *scnr*

Depending on the size of the "license file", you probably still need e.g. AES, because asymmetric cyphers can only be used for "small" amounts of data, typically the same size as the keys used.

What you do is: You use a secret/random key for some symmetric cypher (e.g. AES-CBC) to encrypt the actual secret data (here your "license file"). But then, this key certainly won't be stored in your application, instead you encrypt the key for the symmetric cypher with some asymmetric method (e.g. RSA).
 
Yes. You encrypt a symmetric key on the public key of an asymmetric algorithm. It can only be decrypted by the recipient who owns the private key corresponding to the specified public key.
 
Yes. You encrypt a symmetric key on the public key of an asymmetric algorithm. It can only be decrypted by the recipient who owns the private key corresponding to the specified public key.
Something like that, I kept it a bit vague because it depends on the specific scenario.

Here I'd assume this "license file" contains information about the licensed functionality, so you probably want to hand out some encrypted file to your customer which is then required to unlock functionality of your application. Then I'd assume the key stored in the application is considered "public" (anybody could extract it from the binary).

So, for issuing a license file, you'd probably create a random AES key, encrypt the information with that, and then encrypt the AES key with the private key of your key pair .. and just concatenate both encrypted parts. If the application can decrypt something meaningful with the AES key obtained by decrypting the first "block" of the file with the "public" key, the license is assumed to be authentic.

You might want to also add some cryptographic hash (e.g. SHA256) of the payload data also encrypted with the private key (IOW a "signature") for an explicit authenticity check. You might even want to think about a mechanism for "key management" using several key pairs and adding a possibility to revoke one in case a private key is ever leaked. Well .... "reader's exercise" 😉
 
doesnt really matter
if its worth to be hacked it will be hacked
even if you sign the license file with private key you still have to give the customer the public key
which he can replace in the binary with another public key for which he has the private key
the hacker won't be able to create a license file for the unmodified binary just for the hacked one
 
even if you sign the license file with private key you still have to give the customer the public key
That's why I just now suggested to use the private key for encryption of the license file and give the customer only the encrypted result.

But then,
if its worth to be hacked it will be hacked
of course! And the most likely thing to happen is not attacking the license file at all (if the crypto used isn't idiotically stupid), but "just" removing any checks for it :cool:
 
It can only be decrypted by the recipient who owns the private key corresponding to the specified public key.
I am not sure if this will work for my use-case then.

The application (running on a server owned by a customer) needs to decrypt the license file in order to look at its contents.

How is this supposed to work if i can't publish the private key?

I'll explain a little bit more what this license file is about:

The customer generates a unique id on the server our app should run on.

Then he submits this id to us and we generate a file with some info and this id.

We encrypt the resulting file with AES and give it to the client.

The app requires this file otherwise it won't start.

If the file is present, the app decrypts it, generates the unique id again and compares that to the id stored in the file.

If the app runs on another server, the id generated upon start will be different and the app refuses to start.

If they match, all is good and the app runs.
 
After evaluating a lot of options, I can recommend this: https://wyday.com/limelm/
It's important to understand that 100% security isn't possible. The closest you could get would be relying on some locked-down platform (hardware and OS) exclusively, that's obviously not wanted here.

Doing the checking online gives you more possibilities as well, I guess that's what they are selling .... and sure, this will raise complexity a lot, so indeed better buy a service here than trying to roll your own.

As I understood the requirement in this thread, only offline license verification is wanted, and for that, I'd say "roll your own" is still an option, given you have some basic crypto understanding. Of course, the idea to "hide some key in the binary" won't get you anywhere 😉
 
Sorry, but am sure my boss prefers a free solution. 🤖
He should carefully consider the pros and cons. "Free" suddenly isn't free any more if 50% of your installations are in fact unlicensed and you have no way to even know about it. That's real revenue just lost, most likely a lot more than you would pay for a licensing service.

An offline-only solution as sketched here in this thread will keep the average "skript-kid" from cracking your software, because some skills (reverse-engineering and binary modification) are needed. But if some "cracker group" gets interested, it's not a huge barrier.
 
I didn't mean to say that this is definitely fitting all the use cases and requirements/needs. Just something I can recommend generally.
They do offer non-online options etc. A lot of the tech is also based on machine fingerprinting, detecting whether it's running in a VM, providing floating licenses, expiring keys, trial etc etc.

Personally, I have not found any free solution that comes even close to this. That does not mean that this is the magic bullet for everything.

Sorry, but am sure my boss prefers a free solution. 🤖
Are your working hours free?
 
We can't use online solutions since our app may run on servers without Internet connection.
Then the decision probably depends on how confident you are in your own "fingerprinting".

This fingerprinting is important to prevent just reusing a license file somewhere else, and that's obviously what you already do with your "unique id". It's important that nobody can reproduce an environment (e.g. in a VM) that results in the same fingerprint. If you can trust your method enough, and if you get your crypto "right", there's not much more to gain ... but OTOH I'm pretty sure a specialist in that domain considers possibilities you'd never think of yourself.
 
eternal_noob Maybe this crazy idea using asymmetric cryptography work:

First, your client and server must be able to communicate securely, recognizing each other as valid interlocutors.

You can do this with a personal TLS certificate that your company specifically issues and integrates into both the client and the server, thus creating the secure channel. Nothing without this certificate should be allowed to communicate with your server.

Second, you start with basic authentication with the server for license generation.

At this point, your server must request identification information from your client, to know if it is registered or not. Normally, it can be PC information such as the serial number of the motherboard and the main hard drive. This information must be obtained on the client and sent to the server, along with a digital signature using the server's public key (all your clients must include this file, so they can use it).

Thus, the server verifies whether or not this data is already registered in its activation database. If they are registered, you know that the client has a valid license and will need to authenticate in a second process using the private key that is already registered on the server (I explain this later). But if the data is not registered, you begin the license generation process for the new client.

To generate the license, you can use a physical key that you give to the client. For example: it can be a string of 32 unique characters that are generated using the private key of your activation server through a signature reduction algorithm (such as the one used by Bitcoin or almost all cryptocurrencies when generating their public keys).

Using this key and the data already captured in the initial step, you can generate a message that contains this data, the activation key, a pair of cryptographic keys (public and private) of the client and a digital signature of everything using the server public key.

The client sends it, the server verifies and if everything is fine, your server issues a digital signature (using the client's public key that you have sent to it) that serves as an unlock key for your client. The client will be able to check during startup (you must read the file with that data) if the signature is valid, since it is signed with its own public key and has the private key for decryption and verification.

Once the process is completed, your server has the client registered both in its machine data and its public-private key, your client has a unique license and knows that it will only be able to communicate with the server using the pair of keys that they have exchanged (the public key -private client) and in case they get too smart (delete the key, change hardware, or anything) they must reactivate the license, since the initial physical key is no longer useful because it has been registered as used.

This way you make sure that:

1.- Your client is unique and identified (using PC serial data).
2.- Your client and the server have the same pair of public keys to talk to each other. In this case, the key is the one that the client sends and that has been added as part of the successful activation process.
 
You can try without asymmetric cryptography. The generated AES key can be personalized onto a smart card/token - with a password to access the key. The key cannot be used (to decrypt data) without presenting the password. And issue these tokens/cards to clients. The user (in the application) enters a password to use the key, data is sent to the token, the token decrypts it (having sanction provided by password), and sends the decrypted data to the client. In such a system, of course, you will have to pay the company supplying the crypto tokens.
 
Just for info, entertainment and such - someone here in Germany just got convicted of having breached a data base using evil hacker tools (some phpadmin python and notepad). The judge thought it "hacking" to open some binary in notepad, scroll a bit, and pick up that clear text password. That's a felony now.

I hang my head in shame.

To connect to the topic, stupid lawmakers and judges like this might be your best deterrent. Closely following by that voodoo guy in sales who asks for the signature to be in blood. For no particular reason.

With cryptography, you can only make theft harder and harder, untill it costs more that buying. And someone will still do it for the thrill.
 
We seem to have enough judges to make that a valid option. But you might be better off hiding the key in f.e. the exif data of the icon file.
 
By the way, if you use the asymmetric cryptography scheme, which I talked about in post 6, then online is also not needed. And you don't even need a token. But you need a trusted certification authority. The client himself generates a pair of keys (public and private). The client sends his public key to a trusted certification authority, where it is signed. After which he sends you this signed public key by email. You must have a public key of a trusted certification authority. On it you verify the authenticity of the client’s public key. Next, you generate an AES key and encrypt it using the client’s public key. And you send this encrypted key back to the client - the same way, by email! After which, you send him a file encrypted with an AES key.:-/
 
Of course it can be retrieved.

Why not use public key cryptography to sign and validate the license? Sign with the private key and validate with the public key.
Why you think that AES key can be located with decompilation and the same cannot be done with asymmetric cryptography? The cracker may simply replace your public key with his public key and then generate license or do something of this kind.
 
Back
Top