4

We need to provide a license key to customers for our application. The actual license is XML but we need to encrypt it and then in our program decrypt it. I think it is the following, but am asking to make sure I'm not missing something (the below is updated from encrypting to signing based on the below comments):

  1. On our server create the XML for the key. The key is in the key container on the server.
  2. On our server sign the XML using our private key.
  3. UUEncode the encrypted license so it emails ok.
  4. Email the license to our customer.
  5. The customer puts the license in their app.exe.config file.
  6. The app reads the license from the config file.
  7. The app UUDecodes the license.
  8. The app verifies the signing using our public key. The public key is embedded in the program.
  9. We now have the XML and use the license properties.

Is this the best way to do this? If not, what approach should we take?

If yes, what .NET API should we use for this and are there any links to sample code?

And a giant thank you to all who walked me through this.

David Thielen
  • 383
  • 1
  • 4
  • 13
  • Why not simply send them the XML file? – ThoriumBR Sep 16 '14 at 14:21
  • Because if I send an XML file with numServers='2' they can then change it to numServers='2000'. – David Thielen Sep 16 '14 at 14:24
  • 7
    You don't want encryption, you want signature – Stephane Sep 16 '14 at 14:33
  • And you confusing the role of private and public key – Stephane Sep 16 '14 at 14:34
  • @Stephane I understand that a signature would work too. But what is the downside of encrypting (the upside is we don't show them everything in the key). As to private/public, isn't what I have listed above the way to insure that only I can create the licenses. The program holds the key to decrypt and therefore that key can be seen by anyone who decompiles the program. – David Thielen Sep 16 '14 at 14:37
  • When the program on the client side can decrypt it, everybody can (given enough effort)! They could extract the decryption key or even read the memory while it is decrypting! – ChrisG Sep 16 '14 at 14:41
  • 2
    Private key is used to DECRYPT data, not encrypt it. If you follow through your plan, you'll need to deploy your private key to all your customers. – Stephane Sep 16 '14 at 14:48
  • Don't try to do that yourself: there are many packages that will let you perform license management properly. I do not think you have the knowledge to pull it of yourself – Stephane Sep 16 '14 at 14:49
  • 1
    @Stephane - Wow, I sure got that backwards. Ok, is there a way where only I can encrypt the key and then the program can decrypt it? But if anyone disassembles the program to get the decrypt key, they still cannot encrypt it? – David Thielen Sep 16 '14 at 14:50
  • @DaGardner I accept the possibility that someone can decrypt the key. Put a breakpoint at the right place in the code and it's all there. What I want to avoid is the ability of someone to create an encrypted key. – David Thielen Sep 16 '14 at 14:53
  • Licensing is more about obfuscation than cryptography. If someone is willing to put the effort, he WILL crack your software if it's running on his hardware. You can delay it, but it's rather futile. that's another reason why you shouldn't try to implement a scheme that you do not really understand: if you think you really need DRM, then it makes sense to use a package that isn't trivial to crack open and therefore to use a 3rd party library – Stephane Sep 16 '14 at 14:56
  • What's the point in creating a falsified key when it's trivial to change your code to ignore it ? – Stephane Sep 16 '14 at 14:58
  • @Stephane We do this for two reasons. The first is that the lock on your hose does not stop a professional burglar, but it does stop casual walk-by theft. So it provides some protection. Second, where our library goes, in many cases it must be digitally signed and is in an enterprise. People working for an enterprise are generally unwilling to do that - and if they will often be fired. So it ends up working pretty well in our case. (Not so well if you're writing a game.) – David Thielen Sep 16 '14 at 15:03
  • Every devlopper has been in this situation. Here is the deal: 1/ you don't know how to do that properly 2/ there are packages that do it properly 3/ doing it improperly will cost you money, time and good will from your (legitimate) customers. If you're really sure it's worth the cost, then get a proper copy protection system. Otherwise, don't bother with a half-backed sollution. – Stephane Sep 16 '14 at 15:06
  • @DavidThielen: You can encrypt the data and then sign the ciphertext. (In that case, there would be no reason for the encryption to be [authenticated encryption](http://en.wikipedia.org/wiki/Authenticated_encryption), and you should not confuse [signing](http://en.wikipedia.org/wiki/Digital_signature) with [MACing](http://en.wikipedia.org/wiki/Message_authentication_code). –  Sep 16 '14 at 15:07
  • @RickyDemer & Stephane - ok, I think what is needed based on what you said is we sign the license. (We'll uuencode it first so we don't have to worry about the XML being prettified and then not matching.) Are there any good samples of how to do this in .NET? – David Thielen Sep 16 '14 at 15:19
  • consider reading: http://stackoverflow.com/questions/3002067/how-are-software-license-keys-generated – rook Sep 16 '14 at 15:50

1 Answers1

6

Sign Your License File

You want to sign the data with your private key to create a signature.

  1. Generate a license file
  2. Sign the file with your private key.
  3. Provide the public key with your application
  4. In your program, verify the file contents have not changed with your public key.

The signature cannot be replaced since only you have the private key to sign the license. If any piece of the license file has changed then the verification will fail, and you can stop execution of your program. Notify the user as you see fit. The important part to realize is that you're not stopping them from modifying it, but if they do then they invalidate the license.

Encryption is the wrong route to take because no matter what you would have to hard-code the encryption key somewhere in your application. Signing the data is much more secure.

Here is a nice introduction to how signing data works (opens a PDF).

Signing Data w/ .NET

I believe this MSDN article will show you all you need to digitally sign an XML file in .NET. There is a full code example at the bottom.

You'll need to create your own RsaCryptoServiceProvider, and setup properties to only contain public keys. Then during installation you'll need to export your public key to the service provider using ExportCspBlob(false). You can export your public key in a well known format like PEM and hard-code it. Here's an example with lots example code for working with encoded strings, creating RsaCryptoServiceProviders, etc.

That last link includes an example that exports the private key as well as the public. You don't want to include this!

RoraΖ
  • 12,317
  • 4
  • 51
  • 83
  • I think this is what I need except... It looks like the same key is used to verify the XML. That means anyone who dissasembles my code can get the key, create their own XML, and sign it. Am I missing something? – David Thielen Sep 16 '14 at 15:24
  • I'm not an expert on .NET. I would expect during installation you'd have to export the hard-coded public key into your own RsaCryptoServiceProvider. I've updated my answer with some useful (hopefully) links. – RoraΖ Sep 16 '14 at 16:05
  • Suggested edit - in the last line say "You don't want to INCLUDE this!" – David Thielen Sep 16 '14 at 16:31
  • Oops, good catch! – RoraΖ Sep 16 '14 at 16:39
  • Hey, finding that means I'm starting to understand all this (I think). – David Thielen Sep 16 '14 at 16:44
  • 1
    @RoraΖ "Encrypt the file with your private key (signing it)." Signing and encrypting are 2 very different things. It doesn't really change your answer much, but but it's probably good no not confuse the issue with ambiguous wording. That would go for step 4 as well "In your program, decrypt and verify...". Really all that is needed is the verify bit. – jpheldson Mar 19 '16 at 16:48