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!