I was initially going to use a signed serialized xml file to store license details. In planning, more and more has moved into this "license file" which will allow for us to distribute a single application and control available functions via the supplied license file.
The UI and printed reports are co-branded with distributors logos, so it would be good if this could be embedded into the license. I know this could be done with the serialized xml file but I was wondering what are the pros and cons of storing this data in a compiled assembly?
The license generation tool could compile the assembly with the appropriate properties and resources and sign it.
Update
From what I can see, using serialized xml or an assembly would be pretty similar. From my point of view, assemblies would allow me to add other resources and le开发者_开发技巧aves some flexibility for the future. As soon as the resources get complicated, xml serialization is a pain.Update2
The software only works with our hardware so licence security is not a massive concern. The main aim is to stop the casual user from enabling features that they have not paid for. I would be choosing one over the other for design simplicity!A signed xml license file has few advantages, but they may not be applicaple to your situation:
- You can inspect the contents of it using a simple tool like notepad or a web browser. If you have to manage a lot of licenses and a lot of time goes by, you can check the license scope more easily by simply viewing the file. Even the customer can read you the most important points of his license over the phone.
- If a single application installation can have many licenses assigned to it (per user, per function, etc), it is easier to manage a list of xml files, than to dynamically load assemblies.
- It is easier to create a tool for client-side license creation -> the application would submit an unsigned xml file for signing.
- It's easier for versioning. If a new version of your software has new licensing options, and the old license should work with the upgraded version, depending of your implementation of the singed licensing assembly, you can break the old software.
If you don't have any of these specific needs, go with the assembly-as-a-license option, as it's simpler to implement.
Update
Looking at other answers that popped up after mine - a perfect protection for software running on a local computer does not exist and will likely not exist for a very long time. Don't spend too much time on protecting your software, because if anyone really, really wants to use it for free, he will find a way to do so. Give the users more reasons to use your application and simplify the buying experience.
Going with signing the license in a dll or an external xml file is good enough.
You could use an assembly in lieu of a licence file, but you shouldn't. It has always been possible to remove the digital signing from an assembly; now it's trivial using the Reflexil tool.
See the article CAS Tamper-Proofing is Broken: Consequences for Software Licensing for more details.
A good solution that has always worked for me is to create a license class with all the properties needed such as name, expiration, logos and such. Serialize the class to binary data in memory, then encrypt that and save to a file. Doing it this way doesn't require signing and the file is hack resistant. To read your license simply do the reverse, read the file, unencrypt, unserialize. One caveat to this is that if multiple assemblies are going to read this license file, then the encrypt/unencrypt functions should be in a separate shared assembly.
I wouldn't go with using an assembly as a license file - as others have pointed out it's relatively trivial to break.
I would use a file ( xml or whatever ) then lock it to the users machine. This can be achieved in several ways :
1) Use System.Cryptography.ProtectedData - this just wraps the Windows DPAPI and uses the windows key store ( either per user or per local machine ). This a simple(ish) approach but you will have to using Encoding.UTF8.GetString ( or whatever your encoding is ) to convert back from a byte array. This is simple but not industrial strength as someone could still dig out the key store etc.
2) Use a machine unique ID such as the SID with a symmetric algorithm such as Rijndael or Blowfish and provide the SHA-256 hash of the unencrypted license file as the IV. This is a bit more complex to implement as you'd need to use WMI to find the SID and then use System.Security.Cryptography.RijndaelManaged etc to do the encryption/decryption.
I think using the assembly is creative, but easier to reverse-engineer. After you open the application with reflector, all locations that check the licenses are recognizable as property reads on the license class. Another problem I see is versioning. When version 2.0 comes, your marketing team might require you to accept 1.0 licenses. Your 2.0 software may have a new license class with extra properties which is no longer interchangible with the 1.0 version of the class. You can make workarounds for that, sure, but it will kind of defeat the simplicity of the original design.
I would prefer the assembly version because:
- Instead of .net sign, you can use authenticode (you need a certificate for it, but it’s not that expensive), or you can use both. Than in your application, you can check the signature. This removes the security hole for a tampered .net sign.
- It’s more flexible. You can define an interface for the license assembly which can be later extended.
- You can have some logic in the license assembly.
But remember. It’s just a software protection. The next step would be to use a crypto key (hasp, marx…)
精彩评论