Licensing support. Yay!

This is one of those things that is rather simple conceptually, but translates into a lot of actual petty work.

When the app is started, it looks at several system properties including the CPU model, Windows' MachineGuid value and others, hashes them together to produce an "Installation ID". For example -

$c!f2ZoPxOlnpLWraJZ3F1nm7JcA

The ID stays the same under normal computer use, but it changes with hardware upgrades or when the OS is reinstalled.

The app also generates an "Installation fingerprint" by hashing each of the properties separately and stringing them together. This yields a longer hash -

YQdAXlZR0FLXZ0KpYxlOk8sJ9Z$xtq19!rp6i3C6P5LiUc0J
x2Ynqe29i41qb!1w5wEzot!q0EH8SsLWfY6gvkyoZPtfn3bW
uYnSwItsG8Wh1FkQFWBCaNqdndeiBiDgkrTde$wJUib9wR58
GJ5bQU1Zr1iewtgyRhLWigHyzKDO3oYztT4hMw6MnP6voupb
J6An5QE4!etkMJx!qzOaYmioIOQ0GiQyapcPQeyYLCi4CN28
CEev0!FZFZz3aa$0dCmNnMRBohZ9z6EZH5NxROhokF8pXWVM
9y$bzQAA

Like ID, the fingerprint changes with hardware upgrades and OS reinstalls, but, unlike ID, it changes only in parts. This makes it suitable for detecting incremental changes to the user's computer.

Both ID and Fingerprint identify user's installation, the difference is that the ID is used on the app side and the Fingerprint - on the licensing server side.

Next, ID and fingerprint are submitted to the licensing server, either by the app itself or by a human through a website. When licensing for production use (as opposed to beta or evaluation), the request also includes a license code - a random token that is issued to the user in exchange for payment.

The server responds with a license, which is a short text file that binds together few pieces of information and seals them with an RSA signature of the licensing server.

License code: EVAL-8028-8316-0400
Installation: $c!f2ZoPxOlnpLWraJZ3F1nm7JcA
Expires on:   20/12/2013

J/8natmgEo1fFr0NSBtw3fsderaMsv6gwELBa7P4tsjtkPxO
Y/4z930IfpujPKwen6QB9Gb33q7lyXQNkAVcvMV5hlXwKNV+
eifzJUqyOE1GdmYd8Z4Io0OuFr2V4tD5vnDmYTFoOye4gd67
D40G/hoKgcvGtX82w6bjLTae+vzm7u6GwowTGrbEmqqJDPNI
4Qc6un+aGuOEWEY0X25DkPYnFy/VnPusWgLRma1eTCrmvOqD
T6WX27++Bwq2+YH1Aw+Br9xEQF6SZOBp9OR1Xp/K24vYSN52
MRlLjhrBIQXmJTTepLKAHEsnA3pvdinU6pzpYexygfjtciUm
VZlgvxfUICWI3pKBNRJtlOQKc9LIyr9jVXQ1jP4QVdY5JNZW
y+71b8cSEtWgRRkYVGZMyUXeJjU7AoW/PhDNWdKvDPBwBInQ
QuNqA1ncxjWMRdLYogR/VY41yKYs9cPaFTPFb4y1XLPiqVRK
vEOMMUvE1kArZS/IuC5yB7Jqd3mXlZaRMacwuhWVcd+fgbFj
wVbLJvRRePKEoP/Kk0CtDPIQNdYVxlEwdZi/S+cFMdfZLiWU
o8HFpT247WWEyElUaDahfCREgjPbs9Iw5pik82bm42phns4I
1936WVycSATBQZp3JC1KXX8iQeDBfOgwe3QQcnWIrpclI/oI
57Mknd6bxeI=

For beta and evaluation licenses the "license code" is generated automatically by the licensing server. The large block of gibberish at the bottom of the license is the RSA signature.


When the app starts, it loads the license and verifies it using public key of the licensing server that is embedded in the app.

If the license is valid, the app works as normal. If the license is missing or expired or doesn't match the installation ID, the app disables certain features and periodically nags to do the right thing and what not.


Now, let say I upgraded my box. This screws up the Installation ID and invalidates the license. The app recomputes new ID and Fingerprint and sends them to the licensing server.

This is where Fingerprint comes into play. The server takes old and new fingerprints, chops them into individual hashes and does a "fuzzy" match. If enough hashes match, we can assume an incremental software or hardware change on user's end and re-issue the license for new Installation ID.

If fingerprints are wildly different, then we make fuss and require contacting human tech support.


In conclusion, needless to say that the whole scheme relies on the validation code in the app being trustworthy. If someone pries the app open and replaces selected IFs with NOPs, then obviously no licensing will work.

The answer to that is that the app should implement self-consistency checks and deploy counter-measures when these checks fail. This is a separate and very large and interesting subject ... which I have no plans on covering here :-) A good starting point here would be fravia.org archives and then follow from there.