using System; using System.IO; using System.Xml.Serialization; // For serialization of an object to an XML Document file. using System.Runtime.Serialization.Formatters.Binary; // For serialization of an object to an XML Binary file. using System.IO.IsolatedStorage; // For accessing user isolated data. using System.Reflection; using System.Text; using System.Windows; using System.Windows.Forms; using System.Security; using System.Security.Cryptography; using System.Management; using System.Management.Instrumentation; using System.Collections; using System.ComponentModel.Design; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; namespace Big.Lito.Data //namespace Seq { public class Class1 { } public class License { #region Properties /// /// the license terms. obscured. /// public string LicenseTerms { get; set; } /// /// the signature. /// public string Signature { get; set; } #endregion #region Methods /// /// saves the license to an xml file. /// /// public void Save(String fileName) { Serializer.Save(this, fileName); } /// /// saves the license to a stream as xml. /// /// public void Save(Stream stream) { Serializer.Save(this, stream); } /// /// create a license object from a license file. /// /// /// public static License Load(String fileName) { // read the filename: return Serializer.Load(new FileInfo(fileName)); } /// /// load a license from stream xml data. /// /// /// public static License Load(Stream data) { // read the data stream: return Serializer.Load(data); } #endregion } /// /// handles license authorization. /// public class LicenseAuthorization { /// /// terms of the license agreement: it's not encrypted (but is obscured) /// [Serializable] internal class LicenseTerms { /// /// start date of the license agreement. /// public DateTime StartDate { get; set; } /// /// registered user name for the license agreement. /// public String UserName { get; set; } /// /// the assembly name of the product that is licensed. /// public String ProductName { get; set; } /// /// the last date on which the software can be used on this license. /// public DateTime EndDate { get; set; } /// /// the Fingerprint of user's computer. /// public String FingerPrint { get; set; } /// /// Expired on user's computer. /// public bool Expired { get; set; } /// /// License for technology on user's computer. /// public bool Treko { get; set; } /// /// License for technology on user's computer. /// public bool Treko3D { get; set; } /// /// returns the license terms as an obscure (not human readable) string. /// /// public String GetLicenseString() { using (MemoryStream ms = new MemoryStream()) { // create a binary formatter: BinaryFormatter bnfmt = new BinaryFormatter(); // serialize the data to the memory-steam; bnfmt.Serialize(ms, this); // return a base64 string representation of the binary data: return Convert.ToBase64String(ms.GetBuffer()); } } /// /// returns a binary representation of the license terms. /// /// public byte[] GetLicenseData() { using (MemoryStream ms = new MemoryStream()) { // create a binary formatter: BinaryFormatter bnfmt = new BinaryFormatter(); // serialize the data to the memory-steam; bnfmt.Serialize(ms, this); // return a base64 string representation of the binary data: return ms.GetBuffer(); } } /// /// create a new license-terms object from a string-representation of the binary /// serialization of the licence-terms. /// /// /// internal static LicenseTerms FromString(String licenseTerms) { using (MemoryStream ms = new MemoryStream(Convert.FromBase64String(licenseTerms))) { //try //{// create a binary formatter: BinaryFormatter bnfmt = new BinaryFormatter(); // serialize the data to the memory-steam; object value = bnfmt.Deserialize(ms); if (value is LicenseTerms) return (LicenseTerms)value; else throw new ApplicationException("Invalid Type!"); //} //catch //{ // throw new ApplicationException("Invalid Type!"); //} } } } #region params only for test /// /// start date of the license agreement. /// public static DateTime StartDate { get; set; } /// /// registered user name for the license agreement. /// public static String UserName { get; set; } /// /// registered Expired for the license agreement. /// public static bool Expired { get; set; } /// /// registered Treko for the license agreement. /// public static bool Treko { get; set; } /// /// registered Treko3D for the license agreement. /// public static bool Treko3D { get; set; } /// /// the assembly name of the product that is licensed. /// public static String ProductName { get; set; } /// /// the last date on which the software can be used on this license. /// public static DateTime EndDate { get; set; } public static string Fingerprint { get; set; } #endregion /// /// builds a user-license pack. This includes the public-key that must be embedded in the application, /// and the private key (which must be kept secure) and a license-file for each user, specific to the /// currently executing assembly, with the specified end date. Start date for the user-license file is /// current date. /// /// /// /// public static void GenerateLicensePack(String outputFolder, String[] userNames, DateTime[] endDates) { // if the key files don't exist..create them: if (!File.Exists(outputFolder + "\\privateKey.xml")) GenerateLicenseResources(outputFolder); // generate each user-license for the current assembly: int i = 0; foreach (String userName in userNames) { // generate each license file: GenerateUserLicenseFile(outputFolder, userName, endDates[i++]); } } /// /// generate the public and private key files in the specified folder. /// /// public static void GenerateLicenseResources(String outputFolder) { // create the directory if it doesn't exist: if (!Directory.Exists(outputFolder)) { Directory.CreateDirectory(outputFolder); } // generate the required key files: String publicKeyFile = outputFolder + "\\publicKey.xml"; String privateKeyFile = outputFolder + "\\privateKey.xml"; // create a new private key: String privateKey = GeneratePrivateKey(); // extract the public part of the key: String publicKey = GetPublicKey(privateKey); // save them: File.WriteAllText(publicKeyFile, publicKey); File.WriteAllText(privateKeyFile, privateKey); } /// /// generate a user-license file. /// /// /// /// /// /// /// public static void GenerateUserLicenseFile(String licenseResourceFolder, String userName, DateTime endDate) { // find and load the private key: String privateKeyFile = licenseResourceFolder + "\\privateKey.xml"; bool licExpired = false; bool licTreko = true; bool licTreko3D = true; // check the key file exists: if (File.Exists(privateKeyFile)) { // load the private key: String privateKey = File.ReadAllText(privateKeyFile); String fingerPrint = FingerPrint.Value(); // generate the license file; License license = CreateLicense( DateTime.Now, endDate, Assembly.GetExecutingAssembly().FullName, userName, licExpired, licTreko, licTreko3D, fingerPrint, privateKey ); // save the license file: license.Save(licenseResourceFolder + "\\" + userName + ".lic"); // show success: MessageBox.Show("User License: " + userName + ".lic Created"); } else { // can't find the key-file: MessageBox.Show("Can't find private-key file: " + privateKeyFile); } } /// /// runs a test of the licensing system from: /// C:\temp\user2.lic and C:\temp\user2_publicKey.xml /// public static string TestTestLicense() { string workDir = AppDomain.CurrentDomain.BaseDirectory; string st = ""; License l = License.Load(workDir + @"license.lic"); if (l != null) { try { String pkey = File.ReadAllText(workDir + @"license_publicKey.xml"); st = ValidateLicense(l, pkey); //MessageBox.Show("License is Valid"); if ((st == " ") || (st == "")) return st; else return st; } catch (SecurityException se) { MessageBox.Show("License INVALID: " + se.Message); return st; } } else { return st = "there is no license file"; } } /// /// generate the required files for TestTestLicense() /// C:\temp\user2.lic and C:\temp\user2_publicKey.xml /// public static void SaveDefaultLicense() { String privateKey = GeneratePrivateKey(); String fingerprint = FingerPrint.Default(); String workDir = AppDomain.CurrentDomain.BaseDirectory; DateTime defaultStart = DateTime.Parse("01.01.2018"); DateTime defaultEnd = DateTime.Parse("01.01.2019"); bool licExpired = false; bool licTreko = true; bool licTreko3D = true; License l = CreateLicense(defaultStart, defaultEnd, Assembly.GetExecutingAssembly().FullName, "Simon", licExpired, licTreko, licTreko3D, fingerprint, privateKey); l.Save(workDir + @"user2.lic"); File.WriteAllText(workDir + @"user2_publicKey.xml", GetPublicKey(privateKey)); File.WriteAllText(workDir + @"system_privateKey.xml", privateKey); StartDate = defaultStart; EndDate = defaultEnd; ProductName = Assembly.GetExecutingAssembly().FullName; UserName = "Simon"; } /// /// generate the required files for TestTestLicense() /// C:\temp\user2.lic and C:\temp\user2_publicKey.xml /// //public static void SaveTestLicense(string userName, DateTime startDate, DateTime endDate, bool licExpired, bool licTreko, bool licTreko3D) public static bool SaveTestLicense(string workDir) { try { //string[] NewFile = File.ReadAllLines(workDir + @"SetLic.cen"); string[] NewFile = File.ReadAllLines(workDir); workDir = AppDomain.CurrentDomain.BaseDirectory; System.IO.File.WriteAllText(workDir + @"license_publicKey.xml", NewFile[1]); System.IO.File.WriteAllText(workDir + @"license.lic", NewFile[2] + "\n" + NewFile[3] + "\n" + NewFile[4] + "\n" + NewFile[5] + "\n" + NewFile[6]); return true; } catch { return false; } } /// /// generate a new, private key. this will be the master key for generating license files. /// /// public static String GeneratePrivateKey() { DSACryptoServiceProvider dsa = new DSACryptoServiceProvider(); return dsa.ToXmlString(true); } /// /// get the public key from a private key. this key must be distributed with the application. /// /// /// public static String GetPublicKey(String privateKey) { DSACryptoServiceProvider dsa = new DSACryptoServiceProvider(); dsa.FromXmlString(privateKey); return dsa.ToXmlString(false); } /// /// use a private key to generate a secure license file. the private key must match the public key accessible to /// the system validating the license. /// /// applicable start date for the license file. /// applicable end date for the license file /// applicable product name /// user-name /// computer's fingerprint /// the private key (in XML form) /// secure, public license, validated with the public part of the key public static License CreateLicense(DateTime start, DateTime end, String productName, String userName, bool licExpired, bool licTreko, bool licTreko3D, String fingerprint, String privateKey) { // create the licence terms: LicenseTerms terms = new LicenseTerms() { StartDate = start, EndDate = end, ProductName = productName, UserName = userName, Expired = licExpired, Treko = licTreko, Treko3D = licTreko3D, FingerPrint = fingerprint }; // create the crypto-service provider: DSACryptoServiceProvider dsa = new DSACryptoServiceProvider(); // setup the dsa from the private key: dsa.FromXmlString(privateKey); // get the byte-array of the licence terms: byte[] license = terms.GetLicenseData(); // get the signature: byte[] signature = dsa.SignData(license); // now create the license object: return new License() { LicenseTerms = Convert.ToBase64String(license), Signature = Convert.ToBase64String(signature) }; } /// /// use a private key to generate a secure license file. the private key must match the public key accessible to /// the system validating the license. /// /// applicable start date for the license file. /// applicable end date for the license file /// applicable product name /// user-name /// computer's fingerprint /// the private key (in XML form) /// secure, public license, validated with the public part of the key public static License UpdateLicense(DateTime start, DateTime end, String productName, String userName, bool licExpired, bool licTreko, bool licTreko3D, String fingerprint, String privateKey) { // create the licence terms: LicenseTerms terms = new LicenseTerms() { StartDate = start, EndDate = end, ProductName = productName, UserName = userName, Expired = licExpired, Treko = licTreko, Treko3D = licTreko3D, FingerPrint = fingerprint }; // create the crypto-service provider: DSACryptoServiceProvider dsa = new DSACryptoServiceProvider(); // setup the dsa from the private key: dsa.FromXmlString(privateKey); // get the byte-array of the licence terms: byte[] license = terms.GetLicenseData(); // get the signature: byte[] signature = dsa.SignData(license); // now create the license object: return new License() { LicenseTerms = Convert.ToBase64String(license), Signature = Convert.ToBase64String(signature) }; } /// /// validates the license and if the app should run; if the license is valid the /// method will complete, if not it will throw a security exception. /// /// /// the license object. /// /// thrown if the license is invalid or expired /// public static string ValidateLicense(License license, String publicKey) { // get the valid terms for the license: (this checks the digital signature on the license file) LicenseTerms terms = GetValidTerms(license, publicKey); string st = ""; // ensure a valid license-terms object was returned: if (terms != null) { // validate the date-range of the license terms: if (DateTime.Now.CompareTo(terms.EndDate) <= 0) { if (DateTime.Now.CompareTo(terms.StartDate) >= 0) { // date range is valid... check the product name against the current assembly if (Assembly.GetExecutingAssembly().FullName == terms.ProductName) { string fingerPrint = FingerPrint.GetCompInfoThis(); if (String.Compare(fingerPrint, terms.FingerPrint) == 0) { #region for test only //StartDate = terms.StartDate; //EndDate = terms.EndDate; //ProductName = terms.ProductName; //Fingerprint = terms.FingerPrint; //UserName = terms.UserName; //Expired = terms.Expired; //Treko = terms.Treko; //Treko3D = terms.Treko3D; #endregion Treko = terms.Treko; Treko3D = terms.Treko3D; return st; } else { // computer's fingerprint doesn't match. //throw new SecurityException("Invalid Computer's Fingerprint: " + terms.FingerPrint); return "Invalid Computer's Fingerprint: " + terms.FingerPrint; } } else { // product name doesn't match. //throw new SecurityException("Invalid Product Name: " + terms.ProductName); return "Invalid Product Name: " + terms.ProductName; } } else { // license terms not valid yet. //throw new SecurityException("License Terms Not Valid Until: " + terms.StartDate.ToShortDateString()); return "License Terms Not Valid Until: " + terms.StartDate.ToShortDateString(); } } else { // license terms have expired. //throw new SecurityException("License Terms Expired On: " + terms.EndDate.ToShortDateString()); return "License Terms Expired On: " + terms.EndDate.ToShortDateString(); } } else { // the license file was not valid. //throw new SecurityException("Invalid License File!"); return "Invalid License File!"; } } /// /// validate license file and return the license terms. /// /// /// /// internal static LicenseTerms GetValidTerms(License license, String publicKey) { // create the crypto-service provider: DSACryptoServiceProvider dsa = new DSACryptoServiceProvider(); // setup the provider from the public key: dsa.FromXmlString(publicKey); // get the license terms data: byte[] terms = Convert.FromBase64String(license.LicenseTerms); // get the signature data: byte[] signature = Convert.FromBase64String(license.Signature); // verify that the license-terms match the signature data if (dsa.VerifyData(terms, signature)) return LicenseTerms.FromString(license.LicenseTerms); else throw new SecurityException("Signature Not Verified!"); } } /// /// provides simple, strongly typed xml serialization methods. /// static class Serializer { /// /// returns the serializer for a specific type. /// /// /// private static XmlSerializer getSerializer() { return new XmlSerializer(typeof(T)); } /// /// serializes data of type T to the specified filename. /// /// /// /// public static void Save(T o, String fileName) { using (FileStream fs = File.Open(fileName, FileMode.Create)) { Save(o, fs); } } /// /// serialize data of type T to the specified stream. /// /// /// the type of data to serialize. /// /// /// the object to serialize (must be of type t) /// /// /// the stream to write the serialized data to. /// public static void Save(T o, Stream stream) { getSerializer().Serialize(stream, o); } /// /// get the xml bytes the object of type T is serialized to. /// /// /// /// public static byte[] Save(T o) { using (MemoryStream ms = new MemoryStream()) { // write the data to the memory stream: Save(o, ms); // return the back-buffer: return ms.GetBuffer(); } } /// /// get the xml string the object is seriaized to, using the specified encoding. /// /// /// the type of object to serialize. /// /// /// the object to serialize. /// /// public static String Save(T o, Encoding encoding) { return encoding.GetString(Save(o)); } /// /// loads data of type T from the stream. /// /// /// /// /// public static T Load(Stream stream) { return (T)getSerializer().Deserialize(stream); } /// /// loads the data from the file. /// /// /// /// /// public static T Load(FileInfo file) { try { using (FileStream fs = file.Open(FileMode.Open)) { return Load(fs); } } catch (Exception ex) { //MessageBox.Show("Error: 512"); // No license file found return default(T); } } /// /// deserialize an object of type T from the byte-array of XML data. /// /// /// /// public static T Load(byte[] data) { using (MemoryStream ms = new MemoryStream(data)) { return Load(ms); } } /// /// deserialize an object of type T from the supplied XML data string. /// /// /// /// public static T Load(String data) { return Load(Encoding.ASCII.GetBytes(data)); } } public class FingerPrint { private static string fingerPrint = string.Empty; public static string CPU { get { return cpuId(); } } public static string BIOS { get { return biosId(); } } public static string Base { get { return baseId(); } } public static string GetCompInfo() { string st; st = "CPU >> " + cpuId() + " BIOS >> " + biosId() + " BASE >> " + baseId() + " DISK >> " + cmbHdd_SelectedIndexChanged() + " VIDEO >> " + videoId() + " MAC >> " + macId(); return st; } public static string GetCompInfoThis() { string st; st = "CPU >> " + cpuId() + " BIOS >> " + biosId() + " BASE >> " + baseId() + " DISK >> " + cmbHdd_SelectedIndexChanged() + " VIDEO >> " + videoId() + " MAC >> " + macId(); fingerPrint = GetHash(st); return fingerPrint; } public static string Value() { if (string.IsNullOrEmpty(fingerPrint)) { //fingerPrint = GetHash("CPU >> " + cpuId() + "\nBIOS >> " + biosId() + "\nBASE >> " + baseId() // +"\nDISK >> "+ diskId() + "\nVIDEO >> " + videoId() +"\nMAC >> "+ macId() // ); string st; //String CompInfo; // = FingerPrint.GetCompInfo(); string workDir = AppDomain.CurrentDomain.BaseDirectory; workDir = workDir + @"CompInfo.Licen"; st = System.IO.File.ReadAllText(workDir); try { st = System.IO.File.ReadAllText(workDir); //st = Convert.ToString(CompInfo); MessageBox.Show(st); } catch { MessageBox.Show("No File at - " + workDir); } //st = "CPU >> " + cpuId() + "\nBIOS >> " + biosId() + "\nBASE >> " + baseId() // + "\nDISK >> " + cmbHdd_SelectedIndexChanged() + "\nVIDEO >> " + videoId() + "\nMAC >> " + macId(); //st = "CPU >> BFEBFBFF000306A9\nBIOS >> American Megatrends Inc.0910System Serial Number20140318000000.000000+000ALASKA - 1072009\nBASE >> ASUSTeK COMPUTER INC.Base Board120700628103539\nDISK >> INTEL SSDSC2CT180A3CVMP220601S1180CGN(Standard disk drives)255\nVIDEO >> 25.21.14.1917NVIDIA GeForce GTX 950\nMAC >> 30:85:A9:9D:06:D8"; fingerPrint = GetHash(st); //fingerPrint = GetHash("CPU >> " + cpuId() + "\nBIOS >> " + biosId() + "\nBASE >> " + baseId() // + "\nDISK >> " + cmbHdd_SelectedIndexChanged() + "\nVIDEO >> " + videoId() + "\nMAC >> " + macId() // ); } return fingerPrint; } public static string Default() { string cpuid = cpuId(); string biosid = biosId(); string baseid = baseId(); if (string.IsNullOrEmpty(fingerPrint)) { fingerPrint = GetHash("CPU >> " + cpuId() + "\nBIOS >> " + biosId() + "\nBASE >> " + baseId() + "\nDISK >> " + diskId() + "\nVIDEO >> " + videoId() + "\nMAC >> " + macId() ); } return fingerPrint; } private static string GetHash(string s) { MD5 sec = new MD5CryptoServiceProvider(); ASCIIEncoding enc = new ASCIIEncoding(); byte[] bt = enc.GetBytes(s); return GetHexString(sec.ComputeHash(bt)); } private static string GetHexString(byte[] bt) { string s = string.Empty; for (int i = 0; i < bt.Length; i++) { byte b = bt[i]; int n, n1, n2; n = (int)b; n1 = n & 15; n2 = (n >> 4) & 15; if (n2 > 9) s += ((char)(n2 - 10 + (int)'A')).ToString(); else s += n2.ToString(); if (n1 > 9) s += ((char)(n1 - 10 + (int)'A')).ToString(); else s += n1.ToString(); if ((i + 1) != bt.Length && (i + 1) % 2 == 0) s += "-"; } return s; } #region Original Device ID Getting Code //Return a hardware identifier public static void LoadHDD() { ManagementObjectSearcher mosDisks = new ManagementObjectSearcher("SELECT * FROM Win32_DiskDrive"); string st = ""; foreach (ManagementObject moDisk in mosDisks.Get()) { //cmbHdd.Items.Add(moDisk["Model"].ToString()); st = st + (moDisk["Model"].ToString()); } } public static string cmbHdd_SelectedIndexChanged() { string st = ""; System.Management.ManagementObjectSearcher mosDisks = new System.Management.ManagementObjectSearcher(@"SELECT * FROM Win32_DiskDrive WHERE Index = 0"); foreach (ManagementObject moDisk in mosDisks.Get()) { //(" "Model", "Manufacturer", "Signature", "TotalHeads"); st = st + moDisk["Model"].ToString(); st = st + moDisk["SerialNumber"].ToString(); st = st + moDisk["Manufacturer"].ToString(); st = st + moDisk["TotalHeads"].ToString(); } return st; } private static string identifier(string wmiClass, string wmiProperty, string wmiMustBeTrue) { string result = ""; System.Management.ManagementClass mc = new System.Management.ManagementClass(wmiClass); System.Management.ManagementObjectCollection moc = mc.GetInstances(); foreach (System.Management.ManagementObject mo in moc) { if (mo[wmiMustBeTrue].ToString() == "True") { //Only get the first one if (result == "") { try { result = mo[wmiProperty].ToString(); break; } catch { } } } } return result; } //Return a hardware identifier private static string identifier(string wmiClass, string wmiProperty) { string result = ""; System.Management.ManagementClass mc = new System.Management.ManagementClass(wmiClass); System.Management.ManagementObjectCollection moc = mc.GetInstances(); foreach (System.Management.ManagementObject mo in moc) { //Only get the first one if (result == "") { try { result = mo[wmiProperty].ToString(); break; } catch { } } } return result; } private static string cpuId() { //Uses first CPU identifier available in order of preference //Don't get all identifiers, as very time consuming string retVal = identifier("Win32_Processor", "UniqueId"); if (retVal == "") //If no UniqueID, use ProcessorID { retVal = identifier("Win32_Processor", "ProcessorId"); if (retVal == "") //If no ProcessorId, use Name { retVal = identifier("Win32_Processor", "Name"); if (retVal == "") //If no Name, use Manufacturer { retVal = identifier("Win32_Processor", "Manufacturer"); } //Add clock speed for extra security retVal += identifier("Win32_Processor", "MaxClockSpeed"); } } return retVal; } //BIOS Identifier private static string biosId() { return identifier("Win32_BIOS", "Manufacturer") + identifier("Win32_BIOS", "SMBIOSBIOSVersion") + identifier("Win32_BIOS", "IdentificationCode") + identifier("Win32_BIOS", "SerialNumber") + identifier("Win32_BIOS", "ReleaseDate") + identifier("Win32_BIOS", "Version"); } //Main physical hard drive ID private static string diskId() { return identifier("Win32_DiskDrive", "Model") + identifier("Win32_DiskDrive", "Manufacturer") + identifier("Win32_DiskDrive", "Signature") + identifier("Win32_DiskDrive", "TotalHeads"); } //Motherboard ID private static string baseId() { return identifier("Win32_BaseBoard", "Model") + identifier("Win32_BaseBoard", "Manufacturer") + identifier("Win32_BaseBoard", "Name") + identifier("Win32_BaseBoard", "SerialNumber"); } //Primary video controller ID private static string videoId() { return identifier("Win32_VideoController", "DriverVersion") + identifier("Win32_VideoController", "Name"); } //First enabled network card ID private static string macId() { return identifier("Win32_NetworkAdapterConfiguration", "MACAddress", "IPEnabled"); } #endregion } }