Reputation: 3677
I'm trying to find a solid licensing scheme using Microsoft's LicenseProvider. My thought is to use asynchronous encryption by ways of RSA (RSACryptoServiceProvider with 2048bit keys). I found this to be pretty easy, but I am unsure how secure the mechanism really is. This isn't for fun and needs to copy-protect a number of products (we're talking ~100 installations) in the US. Expiration date is not needed.
Now, I use a private key to encrypt the license file (.lic). On the customer's computer, the license manager will check the computer's unique ID against the unique ID stored in the .lic file at runtime. Since the product will have the corresponding public key it can decrypt the file. If the IDs match, the license is valid and the program starts.
(BTW the computer ID is a combination of: MAC Address + CPU serial + hard drive serial. So if one of those changes, the license wil need to be renewed)
It's that simple? As I see it, even if you could decrypt the .lic file, you could never encrypt it again because you don't have the private key needed.
Now, other than buying a costly 3rd party solution, cracking and circumventing the licensing DLL, how secure do you find this idea of using RSA+computerID?
(Yes, we're looking into obfuscating the code to make this better)
Thanks for the feedback!
Upvotes: 3
Views: 3011
Reputation: 31
Regardless if you obfuscate the code or not, the point is that you technique is not secure and can be defeated. Your product's licensing scheme will only be as secure as your obfuscation.
Rather than using RSA to encrypt a unique ID or license file, consider using RSA to encrypt a module, assembly or class library with the essential core components or certain key functionality that you only want available in the purchased full version. This way, without the proper license, the full version functions or the application's core logic is simply not there, rather than all of your hard work being stolen with a JMP instruction to the entry point of your full version, 'licensed' software.
Fundamentally, the most basic of implementations of this concept would be to make the 'license' that you receive after purchase and have to paste into the program the public key to decrypt the encrypted modules/assembly. You would not want to do this, however, as one person could purchase the 'license' and then give it away to all his or post it on his blog. At the very least, the key that decrypts the full version functionality should be encrypted using another key and included with every copy of the software. The 'license' then would be the public key that decrypts the real key that does the decryption of the protected software. This way you can have multiple versions of the license or change it up if one gets posted on all the popular serials websites.
Going further, the 'license' that encrypts the license would simply be hashed or symmetrically encrypted with the computers 'unique ID', which is provided to the server some time during the payment handling. This way only a that computer can generate the proper 'pass-phrase', if you will, that can recover the key to decrypt the key to decrypt the program/dll/whathaveyou.
Ideally you would decrypt the module into protected memory space that can not be read by other applications and is not paged to disk, then is ran from memory and is overwritten as soon as you are done with it. Sure this technique is not infallible, and a determined reverse engineer could potentially obtain a decrypted module for redistribution, but even for that to happen, someone would have had to purchased a legal license from you somewhere along the line.
Other ideas include storing core functionality or key data structures as compiled machine language or intermediate language, encrypted, and on a server somewhere, that must pass validation in order retrieve that information from the server each time that function needs to be executed, and is decrypted directly into protected memory, from which it is executed, but such level of sophistication is scarcely necessary and doesn't provide a whole lot of added security for the level of complexity involved.
I hope Ive given you some things to think about. Keep in mind, controlling the number of copies that a user makes becomes impossible if the whole thing is decrypted and available for the user to copy, so Id recommend keeping some component encrypted when the application is not executing.
Upvotes: 3
Reputation: 1231
Just for clarification, (which you may have been referring to) you should Sign the data using [provider].SignData([params]) and the to validate the license use [provider].VerifyData([params]). Also not forgetting remove the private key from the key pair you have created.
Upvotes: 1
Reputation: 11
I have the same type of solution. However, I just wanted to point out the obsfuscating the code does not prevent revesere engineering and hacking, it just makes the job of understanding the revese engineered code much more difficult. Obsfuscating is an important step in this process because without it, it is relatively easy to reverse engineeer the code, locate the security methods, and just make them return successful results (i.e. No need to spend months trying to crack the encryptin key, a hacker would just bypass it).
Upvotes: 1