For a high-level primer on copy-protection, please see our blog post "Product Activation: Fingerprints, Copy Protection, Disconnected Computers".
A major aspect of software licensing is copy protection. This prevents an end-user from activating a license on one system and copying that application to another system to gain additional unauthorized licenses. A machine fingerprint is generated and saved in each license file. This fingerprint consists of several attributes known as system identifiers, which may consist of the network adapter's MAC address, the computer name, or other uniquely identifiable data. Each time an application runs, it generates the fingerprint for the current system and compares it to that stored in the license file. If enough of the individual system identifiers match, it is reasonable to believe it is the same system and the application is authorized to run. Otherwise, the user must reactivate. The system fingerprint is also included in the activation request and sent to SOLO Server. If the product option is configured to "Allow Reactivations on Same Computer" then SOLO Server will look for a previously activated installation with a matching fingerprint, and if found, will allow the system to reactivate.
While creating your license implementation class, you should have created a Validate method. This is where you can implement your copy protection logic by adding validation of information in the license and the system running your application.
System identification is the primary means of preventing a license from working on a system other than the one on which it was activated. In other words, if you were to activate an application on Computer A, copy Computer A's license file to Computer B, the application would prevent the application from running on Computer B using Computer A's license file.
More detailed information on each system identifier can be found in the PLUSManaged API documentation under the com.softwarekey.Client.Licensing namespace.
To add basic system identifier validation, we can create a Validate method to look like the following:
The code above checks to make sure the system's current identifiers are an exact match to the identifiers authorized during activation. If the CurrentIdentifiers do not match the AuthorizedIdentifiers in the license file exactly, then the license is rejected by the example above. If you only use a single type of SystemIdentifierAlgorithm, it is possible for you to replace SystemIdentifierValidation.REQUIRE_EXACT_MATCH to a number representing the minimum number of identifiers that must match instead. However, if you use several different SystemIdentifierAlgorithm implementations in your application, then you should consider adding your own, customized validation.
It is possible to customize your validation logic to allow for some amount of acceptable change/variation by comparing the hash values of certain types of CurrentIdentifiers against the hash values of the same type of AuthorizedIdentifiers. To implement this in your application, you can add a new method to your license implementation class, which validates the identifiers using custom logic similar to what is shown below.
//validate one identifier at a time using the specified required number of matches set above in the switch statement
The example code above assumes three types of SystemIdentifierAlgorithm are used by the application, and requires at least one match for the NIC Identifier and exact matches for the other identifiers. Once your customized validation method is implemented, you can update your Validate method to call to it as shown below.