It is very important to understand that no licensing solution can be unbreakable. Once your application is installed on end users machine, the end users have full control over your application's assets to perform anything including reverse engineering, decompiling and tampering. When possible, license checking should always be coupled with security best practices to ensure that it prevents casual piracy and makes it difficult and time consuming for someone trying to tamper with your software application. The following are some guidelines and security best practices that will help you in implementing effective license checking with Secure License Manager.
Make your licensing user friendly
The whole purpose of licensing is to prevent repeated use of a license key (casual piracy) and ensure that your software application can be used only if one has a valid license. Your licensing implementation should be user friendly in that it should enable honest users of your application to use your application without bothering end users. Therefore, it is very important that you take necessary measures to strike a balance and ensure that your licensing implementation is strong but does not interfere with the normal use of your software application.
Buy vs. Build
Building a licensing software from scratch is a very complex and difficult task. Using a third party licensing solution enables you to :
Use strong licensing mechanisms
Secure License Manager uses strong cryptographic technologies to generate license keys. When using public/private key cryptographic techniques, license keys can be generated only using the private key. This private key is something that you will only have and should protect at all times. Because the private key is not shared and is not packaged in your application, it becomes mathematically impossible to create a key generator by someone who is maliciously attempting to tamper with your application.
Repeat & sprinkle license checking
Standard software development practice recommends "DRY" which stands for "Do Not Repeat Yourself." It is a common practice to avoid repeating code fragments and instead create shared/common fragment that is reused elsewhere. However, when it comes to license checking, it is better to repeat and sprinkle the license checking logic in different places. This makes it difficult for a malicious user to identify and isolate the license checking code in your application.
Perform license checking at different levels
License checking should also be done at different levels and at random times. For example,
Protect your assets, assemblies and data
When possible, all of your sensitive assets, assemblies and data should be protected. For example, it is a security best practice to obfuscate and/or encrypt your .NET assemblies so that your intellectual property is not visible to prying eyes using freely available decompiling tools. In addition to obfuscation, it is also very common to encrypt assemblies and decrypt them at runtime only when the assemblies are needed for some use.
Check for tampering
You can also check for tampering of your application during license checking or when your application is first opened. If your components are signed using code signing certificates, you can check that your components/assemblies have valid signatures. You can also keep a hash or checksum of your assets, assemblies and data somewhere (in registry, file or even in your generated license keys) and calculate this hash at runtime when your application is in use to verify that it is the same as your previously stored hash.
Separate Trial/Evaluation versions from licensed versions
In some scenarios it might be beneficial to create a separate set of components or assemblies for trial/evaluation versions. This enables you to hardcode any trial/evaluation limits in your components and there will be no easy way to bypass these limitations. When end users acquire a license from you, you can then allow your end users access for the licensed version which can be installed via a separate installer or your application can automatically download individual components from you website.
Avoid obvious license check failure messages
Showing obvious license check failure messages such as "Invalid License" makes it easier for prying eyes to locate license validation logic in your application. To make it challenging to locate the license checking logic in your application, it is better not to report obvious error messages and instead use coded or numbered error messages such as "Error:1234". It is also security best practices not to report the error message immediately and instead to delay the error message reporting and display the error message at a time when no license validation logic is being executed. If needed you can also report the license validation error message in a separate process.
Embed customer information in license keys
Embedding customer information such as company name, customer name and email in your license keys and displaying this information within your application is a good way to discourage sharing license keys. The license key owner is discouraged from sharing the license key because s/he does not want his/her information displayed in the application when the shared license key is used else where. In the same manner, it is potentially discouraging for the license key borrower as it will be obvious to anyone that the borrower is using an illegally borrowed/shared license.