0

I will deploy a windows application to some client machines. They will run offline. I need to make sure that they cannot move application to another machines. I am able to build my project for every deployment.

So what I thought is: I write a tool for getting the computers cpuID, encrypt it, embed it into a static variable in my application code, build and deploy it to client. Then on applications start, I will get the cpuID with the application itself this time and decrpyt the encrypted cpuID from that static variable, check if they match and allow or reject the launching of the application. So I will only have the decryption algorithm present in the application code.

I need to make sure that even they reverse engineer the code, they cannot create their own encrypted cpuID's and change that static variable.

I need an encryption system which I guess needs to be an asymmetric one but I'm not sure, and bad intentioned people shouldn't be able to understand the way I encrypt the cpuId by looking at the decryption algorithm.

Is something like this even possible? If it is possible what kind of algorithms they are and can I implement them on my own? Or are there any stable implementations?

EDIT: What I am asking is actually an encrpytion algorithm that is not possible the deduce from its decrpytion algorithm. So the question is not actually about software protection. I just wanted to explain how will I use it.

EDIT2: Here is what I am trying to do.

Hash Tool:

public string GetDeviceHashEncrypted(out RSParameters publicKey)
{
    var deviceHash = getComputerHash(); // combination of few things.
    using(var rsa = new RSACryptoServiceProvider())
    {
        publicKey = rsa.ExportParameters(false);
        return new UnicodeEncoding().GetString(rsa.Encrypt(deviceHash, false));
    }
}   

after I get the public key and encrypted data from the hash tool I write them into client apps code manually. And build and deploy it to client.

Client:

public static string EncryptedDeviceHash = ...; //encrypted version of device hash
public static RSAParameters PublicKey = ...; // public key generated by hash tool

...

public bool _validateDevice()
{
    var deviceHash = getComputerHash(); // combination of few things.
    using(var rsa = new RSACryptoServiceProvider())
    {
        rsa.ImportParameters(PublicKey);
        return rsa.Decrypt(EncryptedDeviceHash, false) == deviceHash;
    }
}

But since public key is not for decrypting and since I cannot replicate the same encrypted string I can't do anything with this logic.

Tolga Evcimen
  • 7,112
  • 11
  • 58
  • 91
  • My question is actually about algorithms, software copying is just the domain of my question. Is it really duplicate? – Tolga Evcimen Sep 13 '14 at 08:34
  • In general, you are taking about asymmetric hashing. You could use `RSACryptoServiceProvider` to create public and private keys, and hash the CPUID (at least) to basically create a license key. Storing it as a compiled var doesnt add much vs a file based license since NET apps are easily viewed and decompiled using the various IL* tools. – Ňɏssa Pøngjǣrdenlarp Sep 13 '14 at 12:20
  • I know about decompilations, I am planning to use some obfuscation tools for that. I know its impssible to protect the project, I at least want to make it safe from copy-paste thefts. – Tolga Evcimen Sep 13 '14 at 12:27
  • So `RSACryptoServiceProvider` is good for this job? When they see I used this well known service can't they create their own key? And replace the stored key with it? – Tolga Evcimen Sep 13 '14 at 12:29
  • RSA will allow you to use the Private key on your system to create a hash which your app can verify using the Public Key. It would be very hard to replace the key. Much less hard to decompile even an obfuscated app and comment out the code that tests the hash. – Ňɏssa Pøngjǣrdenlarp Sep 13 '14 at 13:43
  • I should add that sending the CPUId from the user to you in order to create the license key provides another way for "them" to understand your system. For that, you can convert it (plus other info such as app identifiers) to a GUID, so they'd *have* to decompile the app to see whats going on. – Ňɏssa Pøngjǣrdenlarp Sep 13 '14 at 14:06
  • With `RSACryptoServiceProvider` for decryption I need privateKey if I understood it right. But since I will make that test on client side I will need to give client the private key, but I'm sure that's not what we are trying to accomplish :) right? – Tolga Evcimen Sep 15 '14 at 07:21
  • No, you write a small app to create a licence using your Private Key + the "lock" such as CPUID (*plus* something else like perhaps a GUID unique to that app/version). Then in the app being protected, use the PUBLIC key to verify the runtime hash of CPUID + GUID + whatever else against the license. The private key is never exposed. It is not unlike a password hash method and only takes [10-15 lines of code](http://pastebin.com/TwXW6Xxv) to verify the hash. Its is not exactly like in the Question, but that sounds like it would require a new compile per user. – Ňɏssa Pøngjǣrdenlarp Sep 15 '14 at 12:24
  • Our user number is very limited so it is fine to do that for me since I will be changing some other things per user too. But I don't get what you are saying. And I couldn't understand the vb code :/ – Tolga Evcimen Sep 15 '14 at 13:03
  • I have added my code snippet. Is that what you had in mind? – Tolga Evcimen Sep 15 '14 at 13:20
  • Even with a small user base, you likely need the Pub/Priv Key approach or else everything is available in the client to circumvent what you are doing (or create new licenses). Your code is close, but you are not encrypting/decrypting, but creating an Asymmetric Signature on the dev side and then simply verifying it on the client side. – Ňɏssa Pøngjǣrdenlarp Sep 15 '14 at 13:39
  • Yes that's pretty dumb I know. And requires no encryption at all. Since if the codes are exploited then they can easily comment out the test code. Even if it is a server based check what we could do to avoid bad intentioned user to comment out the test code? – Tolga Evcimen Sep 15 '14 at 13:48
  • A given license key should only verify on one machine and for one product, but preventing them from commenting out the test is something different (and mentioned in comment #2), but you can 'lock' an assembly so that it cant be easily disassembled. Having the client phone home for authorization can be simpler crypto-wise but is something altogether different from the OP with new issues (what if your app is firewalled; what about multiusers etc). – Ňɏssa Pøngjǣrdenlarp Sep 15 '14 at 14:06

0 Answers0