Warning: preg_replace(): Compilation failed: invalid range in character class at offset 4 in /home/.sites/946/site2164767/web/blog/wp-content/plugins/crayon-syntax-highlighter/crayon_langs.class.php on line 340 Warning: preg_replace(): Compilation failed: invalid range in character class at offset 4 in /home/.sites/946/site2164767/web/blog/wp-content/plugins/crayon-syntax-highlighter/crayon_langs.class.php on line 340 Warning: preg_replace(): Compilation failed: invalid range in character class at offset 4 in /home/.sites/946/site2164767/web/blog/wp-content/plugins/crayon-syntax-highlighter/crayon_langs.class.php on line 340 Warning: preg_replace(): Compilation failed: invalid range in character class at offset 4 in /home/.sites/946/site2164767/web/blog/wp-content/plugins/crayon-syntax-highlighter/crayon_langs.class.php on line 340 Warning: preg_replace(): Compilation failed: invalid range in character class at offset 4 in /home/.sites/946/site2164767/web/blog/wp-content/plugins/crayon-syntax-highlighter/crayon_langs.class.php on line 340 Warning: preg_replace(): Compilation failed: invalid range in character class at offset 4 in /home/.sites/946/site2164767/web/blog/wp-content/plugins/crayon-syntax-highlighter/crayon_langs.class.php on line 340 Warning: preg_replace(): Compilation failed: invalid range in character class at offset 4 in /home/.sites/946/site2164767/web/blog/wp-content/plugins/crayon-syntax-highlighter/crayon_langs.class.php on line 340 Warning: preg_replace(): Compilation failed: invalid range in character class at offset 4 in /home/.sites/946/site2164767/web/blog/wp-content/plugins/crayon-syntax-highlighter/crayon_langs.class.php on line 340 Warning: preg_replace(): Compilation failed: invalid range in character class at offset 4 in /home/.sites/946/site2164767/web/blog/wp-content/plugins/crayon-syntax-highlighter/crayon_langs.class.php on line 340 Warning: preg_replace(): Compilation failed: invalid range in character class at offset 4 in /home/.sites/946/site2164767/web/blog/wp-content/plugins/crayon-syntax-highlighter/crayon_langs.class.php on line 340 Warning: preg_replace(): Compilation failed: invalid range in character class at offset 4 in /home/.sites/946/site2164767/web/blog/wp-content/plugins/crayon-syntax-highlighter/crayon_langs.class.php on line 340 Warning: preg_replace(): Compilation failed: invalid range in character class at offset 4 in /home/.sites/946/site2164767/web/blog/wp-content/plugins/crayon-syntax-highlighter/crayon_langs.class.php on line 340 Warning: preg_replace(): Compilation failed: invalid range in character class at offset 4 in /home/.sites/946/site2164767/web/blog/wp-content/plugins/crayon-syntax-highlighter/crayon_langs.class.php on line 340 Warning: preg_replace(): Compilation failed: invalid range in character class at offset 4 in /home/.sites/946/site2164767/web/blog/wp-content/plugins/crayon-syntax-highlighter/crayon_langs.class.php on line 340 Warning: preg_replace(): Compilation failed: invalid range in character class at offset 4 in /home/.sites/946/site2164767/web/blog/wp-content/plugins/crayon-syntax-highlighter/crayon_langs.class.php on line 340 Warning: preg_replace(): Compilation failed: invalid range in character class at offset 4 in /home/.sites/946/site2164767/web/blog/wp-content/plugins/crayon-syntax-highlighter/crayon_langs.class.php on line 340 Warning: preg_replace(): Compilation failed: invalid range in character class at offset 4 in /home/.sites/946/site2164767/web/blog/wp-content/plugins/crayon-syntax-highlighter/crayon_langs.class.php on line 340 Warning: preg_replace(): Compilation failed: invalid range in character class at offset 4 in /home/.sites/946/site2164767/web/blog/wp-content/plugins/crayon-syntax-highlighter/crayon_langs.class.php on line 340 Warning: preg_replace(): Compilation failed: invalid range in character class at offset 4 in /home/.sites/946/site2164767/web/blog/wp-content/plugins/crayon-syntax-highlighter/crayon_langs.class.php on line 340 Warning: preg_replace(): Compilation failed: invalid range in character class at offset 4 in /home/.sites/946/site2164767/web/blog/wp-content/plugins/crayon-syntax-highlighter/crayon_langs.class.php on line 340 Warning: preg_replace(): Compilation failed: invalid range in character class at offset 4 in /home/.sites/946/site2164767/web/blog/wp-content/plugins/crayon-syntax-highlighter/crayon_langs.class.php on line 340 Warning: preg_replace(): Compilation failed: invalid range in character class at offset 4 in /home/.sites/946/site2164767/web/blog/wp-content/plugins/crayon-syntax-highlighter/crayon_langs.class.php on line 340 Warning: preg_replace(): Compilation failed: invalid range in character class at offset 4 in /home/.sites/946/site2164767/web/blog/wp-content/plugins/crayon-syntax-highlighter/crayon_langs.class.php on line 340 Warning: preg_replace(): Compilation failed: invalid range in character class at offset 4 in /home/.sites/946/site2164767/web/blog/wp-content/plugins/crayon-syntax-highlighter/crayon_langs.class.php on line 340 Warning: preg_replace(): Compilation failed: invalid range in character class at offset 4 in /home/.sites/946/site2164767/web/blog/wp-content/plugins/crayon-syntax-highlighter/crayon_langs.class.php on line 340 Warning: preg_replace(): Compilation failed: invalid range in character class at offset 4 in /home/.sites/946/site2164767/web/blog/wp-content/plugins/crayon-syntax-highlighter/crayon_langs.class.php on line 340 Warning: preg_replace(): Compilation failed: invalid range in character class at offset 4 in /home/.sites/946/site2164767/web/blog/wp-content/plugins/crayon-syntax-highlighter/crayon_langs.class.php on line 340 Warning: preg_replace(): Compilation failed: invalid range in character class at offset 4 in /home/.sites/946/site2164767/web/blog/wp-content/plugins/crayon-syntax-highlighter/crayon_langs.class.php on line 340 Warning: preg_replace(): Compilation failed: invalid range in character class at offset 4 in /home/.sites/946/site2164767/web/blog/wp-content/plugins/crayon-syntax-highlighter/crayon_langs.class.php on line 340 Warning: preg_replace(): Compilation failed: invalid range in character class at offset 4 in /home/.sites/946/site2164767/web/blog/wp-content/plugins/crayon-syntax-highlighter/crayon_langs.class.php on line 340 Warning: preg_replace(): Compilation failed: invalid range in character class at offset 4 in /home/.sites/946/site2164767/web/blog/wp-content/plugins/crayon-syntax-highlighter/crayon_langs.class.php on line 340 Warning: preg_replace(): Compilation failed: invalid range in character class at offset 4 in /home/.sites/946/site2164767/web/blog/wp-content/plugins/crayon-syntax-highlighter/crayon_langs.class.php on line 340 Warning: preg_replace(): Compilation failed: invalid range in character class at offset 4 in /home/.sites/946/site2164767/web/blog/wp-content/plugins/crayon-syntax-highlighter/crayon_langs.class.php on line 340 Warning: preg_replace(): Compilation failed: invalid range in character class at offset 4 in /home/.sites/946/site2164767/web/blog/wp-content/plugins/crayon-syntax-highlighter/crayon_langs.class.php on line 340 Warning: preg_replace(): Compilation failed: invalid range in character class at offset 4 in /home/.sites/946/site2164767/web/blog/wp-content/plugins/crayon-syntax-highlighter/crayon_langs.class.php on line 340 Warning: preg_replace(): Compilation failed: invalid range in character class at offset 4 in /home/.sites/946/site2164767/web/blog/wp-content/plugins/crayon-syntax-highlighter/crayon_langs.class.php on line 340 Warning: preg_replace(): Compilation failed: invalid range in character class at offset 4 in /home/.sites/946/site2164767/web/blog/wp-content/plugins/crayon-syntax-highlighter/crayon_langs.class.php on line 340 Warning: preg_replace(): Compilation failed: invalid range in character class at offset 4 in /home/.sites/946/site2164767/web/blog/wp-content/plugins/crayon-syntax-highlighter/crayon_langs.class.php on line 340 Warning: preg_replace(): Compilation failed: invalid range in character class at offset 4 in /home/.sites/946/site2164767/web/blog/wp-content/plugins/crayon-syntax-highlighter/crayon_langs.class.php on line 340 Warning: preg_replace(): Compilation failed: invalid range in character class at offset 4 in /home/.sites/946/site2164767/web/blog/wp-content/plugins/crayon-syntax-highlighter/crayon_langs.class.php on line 340 Warning: preg_replace(): Compilation failed: invalid range in character class at offset 4 in /home/.sites/946/site2164767/web/blog/wp-content/plugins/crayon-syntax-highlighter/crayon_langs.class.php on line 340 Warning: preg_replace(): Compilation failed: invalid range in character class at offset 4 in /home/.sites/946/site2164767/web/blog/wp-content/plugins/crayon-syntax-highlighter/crayon_langs.class.php on line 340 Warning: preg_replace(): Compilation failed: invalid range in character class at offset 4 in /home/.sites/946/site2164767/web/blog/wp-content/plugins/crayon-syntax-highlighter/crayon_langs.class.php on line 340 Warning: preg_replace(): Compilation failed: invalid range in character class at offset 4 in /home/.sites/946/site2164767/web/blog/wp-content/plugins/crayon-syntax-highlighter/crayon_langs.class.php on line 340 Warning: preg_replace(): Compilation failed: invalid range in character class at offset 4 in /home/.sites/946/site2164767/web/blog/wp-content/plugins/crayon-syntax-highlighter/crayon_langs.class.php on line 340 Warning: preg_replace(): Compilation failed: invalid range in character class at offset 4 in /home/.sites/946/site2164767/web/blog/wp-content/plugins/crayon-syntax-highlighter/crayon_langs.class.php on line 340 Warning: preg_replace(): Compilation failed: invalid range in character class at offset 4 in /home/.sites/946/site2164767/web/blog/wp-content/plugins/crayon-syntax-highlighter/crayon_langs.class.php on line 340 Warning: preg_replace(): Compilation failed: invalid range in character class at offset 4 in /home/.sites/946/site2164767/web/blog/wp-content/plugins/crayon-syntax-highlighter/crayon_langs.class.php on line 340 Warning: preg_replace(): Compilation failed: invalid range in character class at offset 4 in /home/.sites/946/site2164767/web/blog/wp-content/plugins/crayon-syntax-highlighter/crayon_langs.class.php on line 340 Warning: preg_replace(): Compilation failed: invalid range in character class at offset 4 in /home/.sites/946/site2164767/web/blog/wp-content/plugins/crayon-syntax-highlighter/crayon_langs.class.php on line 340 Warning: preg_replace(): Compilation failed: invalid range in character class at offset 4 in /home/.sites/946/site2164767/web/blog/wp-content/plugins/crayon-syntax-highlighter/crayon_langs.class.php on line 340 Warning: preg_replace(): Compilation failed: invalid range in character class at offset 4 in /home/.sites/946/site2164767/web/blog/wp-content/plugins/crayon-syntax-highlighter/crayon_langs.class.php on line 340 Warning: preg_replace(): Compilation failed: invalid range in character class at offset 4 in /home/.sites/946/site2164767/web/blog/wp-content/plugins/crayon-syntax-highlighter/crayon_langs.class.php on line 340 Warning: preg_replace(): Compilation failed: invalid range in character class at offset 4 in /home/.sites/946/site2164767/web/blog/wp-content/plugins/crayon-syntax-highlighter/crayon_langs.class.php on line 340 Warning: preg_replace(): Compilation failed: invalid range in character class at offset 4 in /home/.sites/946/site2164767/web/blog/wp-content/plugins/crayon-syntax-highlighter/crayon_langs.class.php on line 340 Warning: preg_replace(): Compilation failed: invalid range in character class at offset 4 in /home/.sites/946/site2164767/web/blog/wp-content/plugins/crayon-syntax-highlighter/crayon_langs.class.php on line 340 Warning: preg_replace(): Compilation failed: invalid range in character class at offset 4 in /home/.sites/946/site2164767/web/blog/wp-content/plugins/crayon-syntax-highlighter/crayon_langs.class.php on line 340 Warning: preg_replace(): Compilation failed: invalid range in character class at offset 4 in /home/.sites/946/site2164767/web/blog/wp-content/plugins/crayon-syntax-highlighter/crayon_langs.class.php on line 340 Warning: preg_replace(): Compilation failed: invalid range in character class at offset 4 in /home/.sites/946/site2164767/web/blog/wp-content/plugins/crayon-syntax-highlighter/crayon_langs.class.php on line 340 Warning: preg_replace(): Compilation failed: invalid range in character class at offset 4 in /home/.sites/946/site2164767/web/blog/wp-content/plugins/crayon-syntax-highlighter/crayon_langs.class.php on line 340 Warning: preg_replace(): Compilation failed: invalid range in character class at offset 4 in /home/.sites/946/site2164767/web/blog/wp-content/plugins/crayon-syntax-highlighter/crayon_langs.class.php on line 340 Warning: preg_replace(): Compilation failed: invalid range in character class at offset 4 in /home/.sites/946/site2164767/web/blog/wp-content/plugins/crayon-syntax-highlighter/crayon_langs.class.php on line 340 Warning: preg_replace(): Compilation failed: invalid range in character class at offset 4 in /home/.sites/946/site2164767/web/blog/wp-content/plugins/crayon-syntax-highlighter/crayon_langs.class.php on line 340 Warning: preg_replace(): Compilation failed: invalid range in character class at offset 4 in /home/.sites/946/site2164767/web/blog/wp-content/plugins/crayon-syntax-highlighter/crayon_langs.class.php on line 340 Warning: preg_replace(): Compilation failed: invalid range in character class at offset 4 in /home/.sites/946/site2164767/web/blog/wp-content/plugins/crayon-syntax-highlighter/crayon_langs.class.php on line 340 Warning: preg_replace(): Compilation failed: invalid range in character class at offset 4 in /home/.sites/946/site2164767/web/blog/wp-content/plugins/crayon-syntax-highlighter/crayon_langs.class.php on line 340 Warning: Cannot modify header information - headers already sent by (output started at /home/.sites/946/site2164767/web/blog/wp-content/plugins/crayon-syntax-highlighter/crayon_langs.class.php:340) in /home/.sites/946/site2164767/web/blog/wp-includes/rest-api/class-wp-rest-server.php on line 1723 Warning: Cannot modify header information - headers already sent by (output started at /home/.sites/946/site2164767/web/blog/wp-content/plugins/crayon-syntax-highlighter/crayon_langs.class.php:340) in /home/.sites/946/site2164767/web/blog/wp-includes/rest-api/class-wp-rest-server.php on line 1723 Warning: Cannot modify header information - headers already sent by (output started at /home/.sites/946/site2164767/web/blog/wp-content/plugins/crayon-syntax-highlighter/crayon_langs.class.php:340) in /home/.sites/946/site2164767/web/blog/wp-includes/rest-api/class-wp-rest-server.php on line 1723 Warning: Cannot modify header information - headers already sent by (output started at /home/.sites/946/site2164767/web/blog/wp-content/plugins/crayon-syntax-highlighter/crayon_langs.class.php:340) in /home/.sites/946/site2164767/web/blog/wp-includes/rest-api/class-wp-rest-server.php on line 1723 Warning: Cannot modify header information - headers already sent by (output started at /home/.sites/946/site2164767/web/blog/wp-content/plugins/crayon-syntax-highlighter/crayon_langs.class.php:340) in /home/.sites/946/site2164767/web/blog/wp-includes/rest-api/class-wp-rest-server.php on line 1723 Warning: Cannot modify header information - headers already sent by (output started at /home/.sites/946/site2164767/web/blog/wp-content/plugins/crayon-syntax-highlighter/crayon_langs.class.php:340) in /home/.sites/946/site2164767/web/blog/wp-includes/rest-api/class-wp-rest-server.php on line 1723 Warning: Cannot modify header information - headers already sent by (output started at /home/.sites/946/site2164767/web/blog/wp-content/plugins/crayon-syntax-highlighter/crayon_langs.class.php:340) in /home/.sites/946/site2164767/web/blog/wp-includes/rest-api/class-wp-rest-server.php on line 1723 Warning: Cannot modify header information - headers already sent by (output started at /home/.sites/946/site2164767/web/blog/wp-content/plugins/crayon-syntax-highlighter/crayon_langs.class.php:340) in /home/.sites/946/site2164767/web/blog/wp-includes/rest-api/class-wp-rest-server.php on line 1723 {"id":45,"date":"2015-06-14T23:55:24","date_gmt":"2015-06-14T21:55:24","guid":{"rendered":"http:\/\/blog.zoolway.com\/?p=45"},"modified":"2015-06-15T00:04:32","modified_gmt":"2015-06-14T22:04:32","slug":"using-net-build-in-cryptography-to-rsa-sign-a-software-license","status":"publish","type":"post","link":"https:\/\/blog.zoolway.com\/using-net-build-in-cryptography-to-rsa-sign-a-software-license","title":{"rendered":"Using .NET build-in cryptography to RSA sign a software license"},"content":{"rendered":"

\u00a0“Do we really need that?”<\/h3>\n

Recently I was asked if I could add something like a software license key to an application. It should also be possible to create keys or “licenses” which would expire at a certain date.<\/p>\n

For business I normally suggest to have a good customer relationship and have your usage terms on paper without an implementation of any checks or keys in the software itself. This way you do not start a fight between protecting and cracking your application and establish trust with your customer.
\nAs said, this applies to business where you know your customers. On mass customer markets things are different.<\/p>\n

Nevertheless, this was the requirement brought infront of me.<\/p>\n

Solution: Sign your license contract<\/h3>\n

\"software-license\"<\/a>For the solution I decided not to go for a simple key and maybe name input. It would require to build some sort of algorhythm which would not only have to\u00a0validate the key but also check if it has a expiration date or not. If the customer wants more protection attributes like license taker name, device id or more, things get even more complicated.<\/p>\n

What works very well out there is to have a plain text license agreement which has the necessary information and could contain anything you would like:<\/p>\n

SampleApp License
\nName: Test User
\nExpires:<\/p><\/blockquote>\n

This is human readable and could easily be\u00a0enhanced with more lines with more attributes. Sending the\u00a0license to someone is as easy as\u00a0to send a plain text email. Copy and paste from an email, a website or any other transfer is simple.<\/p>\n

Of course – when you look at this, this is easily to fake. So we need some kind of validation, a secure hash. A hash which can be validated easily but generation is hard and limited to the license giver.<\/p>\n

Implementation<\/h3>\n

Those of you familiar with cryptography will already know what I am after: Asynchronous cryptography to create a signature for the license with a private key which can be validated with a public key. This is not a new idea, it is one of the basic usages of RSA everywhere out there, like the certificates for secured web connections (HTTPS) many of you use for online banking.<\/p>\n

So if we would sign our license, the complete license text could be:<\/p>\n

SampleApp License
\nName: Test User
\nExpires:
\nFJ7xBShqfMqJuvFKdCje6o3pLq7Y9pKC
\nO4D2BSl7vy9jvvUfG9WByEFTgdeSOYSB
\nQShfIs\/4Jm3mErLmE0DElqgivRAmnKHO
\n09RA5B7neiP1KqJOxAfmEBIxMsV9PjhJ
\ntB7s9XQJdkkG1C582imwO\/PCQI9hcbOC
\nmUxj71Iys2c=<\/p><\/blockquote>\n

The trick is: If you change any character here to change your expiration date, name or anything else (even in the hash) the license will be detected to be invalid. This works as the license generator uses a private key to generate the signature hash and your application uses a public key to validate that hash. There are some more things to consider to make this safe but that is the basic idea.<\/p>\n

Does this look similar to you? Yeah, the whole thing is not a new idea to me, there is much software out there already using this kind of approach!<\/p>\n

The implementation of RSA is quite old and well-known. It is based on prime factorisation\u00a0like many cryptography algorithms\u00a0today. And if you would like to do it in .NET, it is even build-in! Unfortunately the web lacks some well-documented example on how to generate a key-pair and how use it for signing and\u00a0validating (and even encrypting and decrypting).<\/p>\n

Use RSACryptoServiceProvider for key generation, import and export<\/h4>\n

So basically, we need to generate a RSACryptoServiceProvider. You can use the default constructor and import\u00a0your RSA settings into the new object or create one with a new keypair with keys of the given size:<\/p>\n

\/\/ generate new keypair with 1024 bit key size\r\nvar csp = new RSACryptoServiceProvider(1024);\r\n\r\n\/\/ create a provider and import Settings\r\nvar csp = new RSACryptoServiceProvider();\r\ncsp.ImportParameters(rsaParams);<\/pre>\n

\"keypair\"<\/a>Normally you would just create a keypair once and save it. That is one of two things the LicenseGenerator project in the example solution attached to this post does. How you save the key is up to you. The RSACryptoServiceProvider has a method ExportParameters which can give you a RSAParameters object with or without the private key. You can serialize that object in any way you would like or use ExportCspBlob\/ImportCspBlob methods of the Provider. The sample solution uses JSON to save the key which is makes it most easy for you to take a look at the contents of the files.<\/p>\n

Your license generator and your application should be completly seperated for obvious reasons. While the generator will require the private key (only you can generate licenses!) and the software will need the public key to validate the given licenses. You might want to embedded the keys as a resource or another way. The example solution only opens files to enable you (and me) to play around with the keys.<\/p>\n

Sign your license<\/h4>\n

Let us now create a String containing our license text which has so be signed. In this sample we will also include a seed\u00a0to make the hash more unpredictable and making cracking the app with exchanging the public key for your own one harder (not impossible!).<\/p>\n

const string SEED = \"plumbum!krum#\";\r\npublic static readonly CultureInfo LICENSE_CULTURE = CultureInfo.InvariantCulture;\r\n\r\nstring internalLicense = String.Format(LICENSE_CULTURE, \"SampleApp License\\nName: {0}\\nExpires: {1}\\n{2}\", name, expirationDate, SEED);<\/pre>\n

Now lets get the signature hash. You can decide which hash algorithm to use – here we use SHA256.<\/p>\n

private static readonly HashAlgorithm HASH_ALGORITHM = new SHA512Managed();\r\n\r\nvar bytesToSign = encoding.GetBytes(internalLicense);\r\nvar hashBytes = csp.SignData(bytesToSign, HASH_ALGORITHM);\r\nvar humanReadableHash = Convert.ToBase64String(hashBytes);<\/pre>\n

Print out the public license where we will not tell them our seed:<\/p>\n

var publicLicense = String.Format(LICENSE_CULTURE, \"SampleApp License\\nName: {0}\\nExpires: {1}\\n{2}\", name, expirationDate, humanReadableHas);<\/pre>\n

This is the text we can send to our license taker.<\/p>\n

Validate the license in your app<\/h4>\n

Your application should have the license saved in its settings and validate it at least on startup. If there is an error or no license is present it should ask the user to enter (copy & paste) one.<\/p>\n

When you have the license, extract your attributes (e.g. name, expiration date, etc.) and the hash into separate variables.<\/p>\n

string name = ...;\r\nDateTime? expirationDate = ...;\r\nstring humanReadableHash = ...;<\/pre>\n

We will take these values and the seed to rebuild the text for the internal license and validate that one against the hash.<\/p>\n

string internalLicense = String.Format(LICENSE_CULTURE, \"SampleApp License\\nName: {0}\\nExpires: {1}\\n{2}\", result.Name, result.Expires, SEED);\r\n\r\nvar csp = GetCryptoServiceProvider(); \/\/ gets the RSA CSP with the public key imported\r\nbool valid = csp.VerifyData(encoding.GetBytes(internalLicense), HASH_ALGORITHM, Convert.FromBase64String(humanReadableHash));\r\n<\/pre>\n

If you have additional attributes like an optional expiration date (nullable\u00a0DateTime used here)\u00a0you have to check that one as well.<\/p>\n

There are many other considerations to make this really safe and get the crackers to have a\u00a0hard job. Question is how to balance effort and outcome.\u00a0It depends also on how many customers use your application and how trustworthy those are. But that is not the discussion here today. Basic recommendation here only include:\u00a0Duplicate the important “constants” like hash algorhythm and\u00a0seed. Make sure you only deliver the public key with your application.<\/p>\n

Summary<\/h3>\n

Here we see that utilizing RSA signing only involves a few lines of code in .NET and some conversion to and from\u00a0byte arrays. There is much you can do in addition to increase safety (sign your assembly, check NTP server,\u00a0e.g.) and to increase user comfort (break the hash into multiple nice lines and put back together, trim whitespace, generate keys and validate in background threads). But the basic is just: Create CSP and generate keys or import them, sign some data, validate some data.<\/p>\n

Note: This post and example can also be a start to use the .NET RSACryptoServiceProvider to implement encryption and decryption.<\/p>\n

Download sample: RsaSigning Sample Solution<\/a>\u00a0(2 sample projects, one to generate keys and licenses, one to represent a protected application; both with simple WPF user interface powered by Caliburn.Micro; will require nuget package restore)<\/p>\n","protected":false},"excerpt":{"rendered":"

\u00a0“Do we really need that?” Recently I was asked if I could add something like a software license key to an application. It should also be possible to create keys or “licenses” which would...<\/p>\n","protected":false},"author":2,"featured_media":54,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[4],"tags":[5,10,6,9,7,8],"_links":{"self":[{"href":"https:\/\/blog.zoolway.com\/wp-json\/wp\/v2\/posts\/45"}],"collection":[{"href":"https:\/\/blog.zoolway.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.zoolway.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.zoolway.com\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.zoolway.com\/wp-json\/wp\/v2\/comments?post=45"}],"version-history":[{"count":4,"href":"https:\/\/blog.zoolway.com\/wp-json\/wp\/v2\/posts\/45\/revisions"}],"predecessor-version":[{"id":52,"href":"https:\/\/blog.zoolway.com\/wp-json\/wp\/v2\/posts\/45\/revisions\/52"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blog.zoolway.com\/wp-json\/wp\/v2\/media\/54"}],"wp:attachment":[{"href":"https:\/\/blog.zoolway.com\/wp-json\/wp\/v2\/media?parent=45"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.zoolway.com\/wp-json\/wp\/v2\/categories?post=45"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.zoolway.com\/wp-json\/wp\/v2\/tags?post=45"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}