Encrypted server control licensing? Naahh...

Note: this entry has moved.

I'd think more than twice before implementing the Encrypted Licence Scheme proposed by Nikhil Kotari. He's proposing to embed the bytes of the key in the assembly itself, and use that as the encryption (for the generator) and decryption (at run-time).
Any decent programmer knows that dumping the IL code with ILDASM will easily expose those bytes as follows (even in Release mode compilation):

.data D_00002408 = bytearray (
                 35 46 42 32 38 31 46 36)                         // 5FB281F6

Now you can write a trivial console app to hack the expiration limit proposed in the same document, for example:

[STAThread]
static void Main(string[] args)
{
  byte[] encryptionKeyBytes = ASCIIEncoding.ASCII.GetBytes("5FB281F6");
  string license;

  DESCryptoServiceProvider des = new DESCryptoServiceProvider();
  des.Key = encryptionKeyBytes;
  des.IV = encryptionKeyBytes;

  // Read the encrypted file.
  ICryptoTransform desDecryptor = des.CreateDecryptor();
  using (FileStream fs = new FileStream(@"..\..\LicensedControls.EncryptedLicensedLabel.lic", FileMode.Open))
  {
    using (Stream crypt = new CryptoStream(fs, desDecryptor, CryptoStreamMode.Read))
    {
      byte[] licbytes = new byte[fs.Length];
            crypt.Read(licbytes, 0, licbytes.Length);
      license = UTF8Encoding.UTF8.GetString(licbytes);
    }
  }

  Console.WriteLine("Decrypted licence: {0}", license);
  
  // Spoof the license with a bigger limit.
  license = String.Concat(
    license.Substring(0, license.LastIndexOf(".") + 1), 
    ";", Int32.MaxValue);
  Console.WriteLine("Hacked licence: {0}", license);

  // Persist it encrypted again.
  ICryptoTransform desEncryptor = des.CreateEncryptor();
  using (FileStream fs = new FileStream(@"..\..\LicensedControls.EncryptedLicensedLabel.lic", FileMode.Create))
  {
    using (CryptoStream crypt = new CryptoStream(fs, desEncryptor, CryptoStreamMode.Write))
    {
      byte[] licbytes = UTF8Encoding.UTF8.GetBytes(license);
      crypt.Write(licbytes, 0, licbytes.Length);
      crypt.FlushFinalBlock();
    }
    fs.Flush();
  }

  Console.WriteLine("Finished");
  Console.ReadLine();
}

Voila! Now your licensed control can be used almost forever without expiration (I could have used Int64.MaxValue to get even more, but you get the idea).
I believe we have to come up with a better solution. Maybe signing the license file with the assembly private key (sn.exe-generated), and then checking its integrity with the assembly public key... what about building something like that right inside ASP.NET 2.0? That would really great!

5 Comments

  • If you're using ILDASM, you could also remove the LicenseProvider attribute and recompile... Obfuscation could make things a little harder to do. However, I agree with you that a asymmetric encryption (with public/private keypair) could be safer to do the encryption.

  • Surely, any serious component developer should sign its assemblies and give them a strong name, thus eliminating the possility of spoofing the code by re-assembling it with ILASM.

    About obfuscation, I don't think it's really relevant. Intellectual property is sufficiently protected by good licenses. Any decent library of controls/components would contain so much code that only understanding it without help would be extremely dificult to anyone even if they have Salamander, Reflector or whatever at hand. Go try yourself to decompile and make use of part of Reflector for example...

  • I guess I didn't state my point very clearly. My point of view is that if someone really want to hack/crack your component's license scheme, he will succeed. You can try to make it harder by using a set of a set assemblies with a strong name referencing each other, obfuscation and even asynchronous encryption of the scheme. But that won't stop an advanced and determined cracker. IMHO, we can best focus on less harder licensing schemes and better components. If a great component is priced according to what it delivers, the author will receive registration fees of honest developers... But this is a completely different discussion :)

  • I believe the assembly signing plus a good license encryption scheme wouldn't take much time to anyone. Writing better components is out of the question, as is the pricing scheme. In fact, as the founder of NMatrix opensource project, I'm more inclined to favor open distribution and support/extension fees.

    But what is undeniable is that we, if protecting our products and making money out of them is a goal, have to give it a careful thought. It's only irresponsible to come out with such a trivial scheme. You're not going to stop piracy, but at least try no to make it a kids game!

  • ok guys



    Daniel wrote:

    Maybe signing the license file with the assembly private key (sn.exe-generated), and then checking its integrity with the assembly public key...



    so...



    Can you write more about signing the license file?



    Some samples...



    thanks in advance



    Gabriel

Comments have been disabled for this content.