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!