Moved from modified DLL to License Generator implementation
Replaced the previous licensing mechanism (based on a modified DLL) with a full-featured License Generator that includes: - Hardware ID detection - File and registry-based license storage The new Generator supports: - Multiple product types (only UIWinForms Tested)
This commit is contained in:
@@ -0,0 +1,86 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace BunifuLicenseGenerator
|
||||
{
|
||||
public class Cryptography
|
||||
{
|
||||
private const string SHA_KEY = "011c3c04-09f0-42ea-8932-f413a9d67a6b";
|
||||
|
||||
private static RijndaelManaged NewRijndaelManaged( string salt )
|
||||
{
|
||||
bool flag = salt == null;
|
||||
if (flag)
|
||||
{
|
||||
throw new ArgumentNullException("salt");
|
||||
}
|
||||
byte[] bytes = Encoding.ASCII.GetBytes(salt);
|
||||
Rfc2898DeriveBytes rfc2898DeriveBytes = new Rfc2898DeriveBytes("011c3c04-09f0-42ea-8932-f413a9d67a6b", bytes);
|
||||
RijndaelManaged rijndaelManaged = new RijndaelManaged();
|
||||
rijndaelManaged.Key = rfc2898DeriveBytes.GetBytes(rijndaelManaged.KeySize / 8);
|
||||
rijndaelManaged.IV = rfc2898DeriveBytes.GetBytes(rijndaelManaged.BlockSize / 8);
|
||||
return rijndaelManaged;
|
||||
}
|
||||
public static string Encrypt( string plainText )
|
||||
{
|
||||
byte[] saltBytes = Encoding.ASCII.GetBytes(SHA_KEY);
|
||||
Rfc2898DeriveBytes rfc2898DeriveBytes = new Rfc2898DeriveBytes("011c3c04-09f0-42ea-8932-f413a9d67a6b", saltBytes);
|
||||
|
||||
RijndaelManaged rijndaelManaged = new RijndaelManaged();
|
||||
rijndaelManaged.Key = rfc2898DeriveBytes.GetBytes(rijndaelManaged.KeySize / 8);
|
||||
rijndaelManaged.IV = rfc2898DeriveBytes.GetBytes(rijndaelManaged.BlockSize / 8);
|
||||
|
||||
ICryptoTransform encryptor = rijndaelManaged.CreateEncryptor(rijndaelManaged.Key, rijndaelManaged.IV);
|
||||
using (MemoryStream ms = new MemoryStream())
|
||||
{
|
||||
using (CryptoStream cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write))
|
||||
{
|
||||
using (StreamWriter sw = new StreamWriter(cs))
|
||||
{
|
||||
sw.Write(plainText);
|
||||
}
|
||||
}
|
||||
return Convert.ToBase64String(ms.ToArray());
|
||||
}
|
||||
}
|
||||
|
||||
public static string Decrypt( string cipherText )
|
||||
{
|
||||
if (!IsBase64String(cipherText))
|
||||
throw new Exception("The cipherText input parameter is not base64 encoded");
|
||||
|
||||
byte[] saltBytes = Encoding.ASCII.GetBytes(SHA_KEY);
|
||||
Rfc2898DeriveBytes rfc2898DeriveBytes = new Rfc2898DeriveBytes("011c3c04-09f0-42ea-8932-f413a9d67a6b", saltBytes);
|
||||
|
||||
RijndaelManaged rijndaelManaged = new RijndaelManaged();
|
||||
rijndaelManaged.Key = rfc2898DeriveBytes.GetBytes(rijndaelManaged.KeySize / 8);
|
||||
rijndaelManaged.IV = rfc2898DeriveBytes.GetBytes(rijndaelManaged.BlockSize / 8);
|
||||
|
||||
ICryptoTransform decryptor = rijndaelManaged.CreateDecryptor(rijndaelManaged.Key, rijndaelManaged.IV);
|
||||
byte[] encryptedBytes = Convert.FromBase64String(cipherText);
|
||||
|
||||
using (MemoryStream ms = new MemoryStream(encryptedBytes))
|
||||
{
|
||||
using (CryptoStream cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Read))
|
||||
{
|
||||
using (StreamReader sr = new StreamReader(cs))
|
||||
{
|
||||
return sr.ReadToEnd();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static bool IsBase64String( string base64String )
|
||||
{
|
||||
base64String = base64String.Trim();
|
||||
return base64String.Length % 4 == 0 && Regex.IsMatch(base64String, "^[a-zA-Z0-9\\+/]*={0,3}$", RegexOptions.None);
|
||||
}
|
||||
public Cryptography()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,239 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.Management;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
|
||||
namespace BunifuLicenseGenerator
|
||||
{
|
||||
[DebuggerStepThrough]
|
||||
public class Hardware
|
||||
{
|
||||
public static string GetUniqueID()
|
||||
{
|
||||
return Hardware.Value();
|
||||
}
|
||||
|
||||
|
||||
public static string GetOSName()
|
||||
{
|
||||
string text = string.Empty;
|
||||
try
|
||||
{
|
||||
ManagementObjectSearcher managementObjectSearcher = new ManagementObjectSearcher("SELECT Caption FROM Win32_OperatingSystem");
|
||||
using (ManagementObjectCollection.ManagementObjectEnumerator enumerator = managementObjectSearcher.Get().GetEnumerator())
|
||||
{
|
||||
if (enumerator.MoveNext())
|
||||
{
|
||||
ManagementObject managementObject = (ManagementObject)enumerator.Current;
|
||||
text = managementObject["Caption"].ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return Hardware.Value();
|
||||
}
|
||||
|
||||
private static string Value()
|
||||
{
|
||||
bool flag = string.IsNullOrEmpty(Hardware._fingerPrint);
|
||||
if (flag)
|
||||
{
|
||||
Hardware._fingerPrint = Hardware.GetHash(string.Concat(new string[]
|
||||
{
|
||||
"CPU >> ",
|
||||
Hardware.CpuId(),
|
||||
"\nBIOS >> ",
|
||||
Hardware.BiosId(),
|
||||
"\nBASE >> ",
|
||||
Hardware.BaseId(),
|
||||
"\nVIDEO >> ",
|
||||
Hardware.VideoId()
|
||||
}));
|
||||
}
|
||||
return Hardware._fingerPrint;
|
||||
}
|
||||
|
||||
private static string GetHash( string s )
|
||||
{
|
||||
MD5 md = new MD5CryptoServiceProvider();
|
||||
byte[] bytes = Encoding.ASCII.GetBytes(s);
|
||||
return Hardware.GetHexString(md.ComputeHash(bytes));
|
||||
}
|
||||
|
||||
private static string GetHexString( IList<byte> bt )
|
||||
{
|
||||
string text = string.Empty;
|
||||
for (int i = 0; i < bt.Count; i++)
|
||||
{
|
||||
byte b = bt[i];
|
||||
int num = (int)b;
|
||||
int num2 = num & 15;
|
||||
int num3 = (num >> 4) & 15;
|
||||
bool flag = num3 > 9;
|
||||
if (flag)
|
||||
{
|
||||
text += ((char)(num3 - 10 + 65)).ToString(CultureInfo.InvariantCulture);
|
||||
}
|
||||
else
|
||||
{
|
||||
text += num3.ToString(CultureInfo.InvariantCulture);
|
||||
}
|
||||
bool flag2 = num2 > 9;
|
||||
if (flag2)
|
||||
{
|
||||
text += ((char)(num2 - 10 + 65)).ToString(CultureInfo.InvariantCulture);
|
||||
}
|
||||
else
|
||||
{
|
||||
text += num2.ToString(CultureInfo.InvariantCulture);
|
||||
}
|
||||
bool flag3 = i + 1 != bt.Count && (i + 1) % 2 == 0;
|
||||
if (flag3)
|
||||
{
|
||||
text += "-";
|
||||
}
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
private static string Identifier( string wmiClass, string wmiProperty, string wmiMustBeTrue )
|
||||
{
|
||||
string text = "";
|
||||
ManagementClass managementClass = new ManagementClass(wmiClass);
|
||||
ManagementObjectCollection instances = managementClass.GetInstances();
|
||||
foreach (ManagementBaseObject managementBaseObject in instances)
|
||||
{
|
||||
bool flag = managementBaseObject[wmiMustBeTrue].ToString() != "True";
|
||||
if (!flag)
|
||||
{
|
||||
bool flag2 = text != "";
|
||||
if (!flag2)
|
||||
{
|
||||
try
|
||||
{
|
||||
text = managementBaseObject[wmiProperty].ToString();
|
||||
break;
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
private static string Identifier( string wmiClass, string wmiProperty )
|
||||
{
|
||||
string text = "";
|
||||
ManagementClass managementClass = new ManagementClass(wmiClass);
|
||||
ManagementObjectCollection instances = managementClass.GetInstances();
|
||||
foreach (ManagementBaseObject managementBaseObject in instances)
|
||||
{
|
||||
bool flag = text != "";
|
||||
if (!flag)
|
||||
{
|
||||
try
|
||||
{
|
||||
bool flag2 = managementBaseObject[wmiProperty] != null;
|
||||
if (flag2)
|
||||
{
|
||||
text = managementBaseObject[wmiProperty].ToString();
|
||||
}
|
||||
break;
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
private static string CpuId()
|
||||
{
|
||||
string text = Hardware.Identifier("Win32_Processor", "UniqueId");
|
||||
bool flag = text != "";
|
||||
string text2;
|
||||
if (flag)
|
||||
{
|
||||
text2 = text;
|
||||
}
|
||||
else
|
||||
{
|
||||
text = Hardware.Identifier("Win32_Processor", "ProcessorId");
|
||||
bool flag2 = text != "";
|
||||
if (flag2)
|
||||
{
|
||||
text2 = text;
|
||||
}
|
||||
else
|
||||
{
|
||||
text = Hardware.Identifier("Win32_Processor", "Name");
|
||||
bool flag3 = text == "";
|
||||
if (flag3)
|
||||
{
|
||||
text = Hardware.Identifier("Win32_Processor", "Manufacturer");
|
||||
}
|
||||
text += Hardware.Identifier("Win32_Processor", "MaxClockSpeed");
|
||||
text2 = text;
|
||||
}
|
||||
}
|
||||
return text2;
|
||||
}
|
||||
|
||||
private static string BiosId()
|
||||
{
|
||||
return string.Concat(new string[]
|
||||
{
|
||||
Hardware.Identifier("Win32_BIOS", "Manufacturer"),
|
||||
Hardware.Identifier("Win32_BIOS", "SMBIOSBIOSVersion"),
|
||||
Hardware.Identifier("Win32_BIOS", "IdentificationCode"),
|
||||
Hardware.Identifier("Win32_BIOS", "SerialNumber"),
|
||||
Hardware.Identifier("Win32_BIOS", "ReleaseDate"),
|
||||
Hardware.Identifier("Win32_BIOS", "Version")
|
||||
});
|
||||
}
|
||||
|
||||
private static string DiskId()
|
||||
{
|
||||
return Hardware.Identifier("Win32_DiskDrive", "Model") + Hardware.Identifier("Win32_DiskDrive", "Manufacturer") + Hardware.Identifier("Win32_DiskDrive", "Signature") + Hardware.Identifier("Win32_DiskDrive", "TotalHeads");
|
||||
}
|
||||
|
||||
private static string BaseId()
|
||||
{
|
||||
return Hardware.Identifier("Win32_BaseBoard", "Model") + Hardware.Identifier("Win32_BaseBoard", "Manufacturer") + Hardware.Identifier("Win32_BaseBoard", "Name") + Hardware.Identifier("Win32_BaseBoard", "SerialNumber");
|
||||
}
|
||||
|
||||
private static string VideoId()
|
||||
{
|
||||
return Hardware.Identifier("Win32_VideoController", "DriverVersion") + Hardware.Identifier("Win32_VideoController", "Name");
|
||||
}
|
||||
|
||||
private static string MacId()
|
||||
{
|
||||
return Hardware.Identifier("Win32_NetworkAdapterConfiguration", "MACAddress", "IPEnabled");
|
||||
}
|
||||
|
||||
public Hardware()
|
||||
{
|
||||
}
|
||||
|
||||
// Note: this type is marked as 'beforefieldinit'.
|
||||
static Hardware()
|
||||
{
|
||||
}
|
||||
|
||||
private static string _fingerPrint = string.Empty;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,179 @@
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
public class LicenseGenerator
|
||||
{
|
||||
|
||||
public enum ProductType
|
||||
{
|
||||
UIWinForms = 0,
|
||||
Charts = 1,
|
||||
DatavizBasicWinForms = 2,
|
||||
DatavizAdvancedWinForms = 3
|
||||
}
|
||||
|
||||
public class Product
|
||||
{
|
||||
public int id { get; set; }
|
||||
public ProductType name { get; set; }
|
||||
public string uuid { get; set; }
|
||||
}
|
||||
|
||||
public class Client
|
||||
{
|
||||
public int ID { get; set; }
|
||||
public int TeamID { get; set; }
|
||||
public int WPUserID { get; set; }
|
||||
public bool IsTeamAdmin { get; set; }
|
||||
public string Name { get; set; }
|
||||
public string Email { get; set; }
|
||||
public bool Blocked { get; set; }
|
||||
public DateTime CreatedAt { get; set; }
|
||||
}
|
||||
|
||||
public class Device
|
||||
{
|
||||
public int ID { get; set; }
|
||||
public string Name { get; set; }
|
||||
public string OS { get; set; }
|
||||
public string HardwareID { get; set; }
|
||||
public bool Blocked { get; set; }
|
||||
public DateTime LastSeen { get; set; }
|
||||
}
|
||||
|
||||
public class License
|
||||
{
|
||||
public int ID { get; set; }
|
||||
public string UUID { get; set; }
|
||||
public int? BundleID { get; set; }
|
||||
public int? TeamID { get; set; }
|
||||
public int? UserID { get; set; }
|
||||
public int PurchaseID { get; set; }
|
||||
public int TotalDays { get; set; }
|
||||
public int MaxDevices { get; set; }
|
||||
public int Activations { get; set; }
|
||||
public int RemainingDevices { get; set; }
|
||||
public string Plan { get; set; }
|
||||
public string RenewalURL { get; set; }
|
||||
public string LicenseKey { get; set; }
|
||||
public DateTime CreatedAt { get; set; }
|
||||
public DateTime ExpiryDate { get; set; }
|
||||
public ProductType Product { get; set; }
|
||||
public List<Product> ProductsLicensed { get; set; }
|
||||
public int Type { get; set; }
|
||||
public int Status { get; set; }
|
||||
}
|
||||
|
||||
public class LicenseRecord
|
||||
{
|
||||
public bool IsValid { get; set; }
|
||||
public int ID { get; set; }
|
||||
public string UUID { get; set; }
|
||||
public string LicenseKey { get; set; }
|
||||
public string CreatedAt { get; set; }
|
||||
public string LastSeen { get; set; }
|
||||
public string RemovedAt { get; set; }
|
||||
public Client Client { get; set; }
|
||||
public Device Device { get; set; }
|
||||
public License License { get; set; }
|
||||
}
|
||||
|
||||
public static string GenerateLicense( ProductType productType, string email, string name, string licenseKey, bool enterprise )
|
||||
{
|
||||
return JsonConvert.SerializeObject(new LicenseRecord
|
||||
{
|
||||
IsValid = true,
|
||||
ID = 123456,
|
||||
UUID = "Fake-license-uuid-12345",
|
||||
LicenseKey = licenseKey,
|
||||
CreatedAt = DateTime.Now.ToString("o"),
|
||||
LastSeen = "0001-01-01T00:00:00",
|
||||
RemovedAt = "0001-01-01T00:00:00",
|
||||
Client = new Client
|
||||
{
|
||||
Blocked = false,
|
||||
IsTeamAdmin = false,
|
||||
ID = 345678,
|
||||
TeamID = 0,
|
||||
WPUserID = 0,
|
||||
Name = name,
|
||||
Email = email,
|
||||
CreatedAt = DateTime.Now
|
||||
},
|
||||
Device = new Device
|
||||
{
|
||||
ID = 789012,
|
||||
Name = Environment.MachineName,
|
||||
OS = Environment.OSVersion.ToString(),
|
||||
HardwareID = BunifuLicenseGenerator.Hardware.GetUniqueID(),
|
||||
Blocked = false,
|
||||
LastSeen = DateTime.Now
|
||||
},
|
||||
License = new License
|
||||
{
|
||||
ID = 987654,
|
||||
UUID = "Fake-license-plan-uuid-67890",
|
||||
BundleID = null,
|
||||
TeamID = null,
|
||||
UserID = null,
|
||||
PurchaseID = 112233,
|
||||
TotalDays = enterprise ? 9999 : 365,
|
||||
MaxDevices = 5,
|
||||
Activations = 1,
|
||||
RemainingDevices = enterprise ? 9999 : 4,
|
||||
Plan = enterprise ? "Enterprise Plan" : "Premium Plan",
|
||||
RenewalURL = null,
|
||||
LicenseKey = null,
|
||||
CreatedAt = DateTime.Now,
|
||||
ExpiryDate = enterprise ? DateTime.Now.AddYears(30) : DateTime.Now.AddYears(1),
|
||||
Product = productType,
|
||||
ProductsLicensed = new List<Product>
|
||||
{
|
||||
new Product
|
||||
{
|
||||
id = (int)productType,
|
||||
name = productType,
|
||||
uuid = null
|
||||
}
|
||||
},
|
||||
Type = enterprise ? 2 : 1,
|
||||
Status = 0
|
||||
}
|
||||
}, Newtonsoft.Json.Formatting.None);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static void SaveLicenseToFile( string encryptedData, ProductType productType )
|
||||
{
|
||||
string programDataPath = Path.Combine(
|
||||
Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData),
|
||||
"Bunifu Technologies"
|
||||
);
|
||||
|
||||
string productFolder = Path.Combine(programDataPath, productType.ToString());
|
||||
Directory.CreateDirectory(productFolder);
|
||||
|
||||
string licenseFilePath = Path.Combine(productFolder, "License.lic");
|
||||
|
||||
File.WriteAllText(licenseFilePath, encryptedData);
|
||||
}
|
||||
public static void SaveLicenseToRegistry( string encryptedData, ProductType productType )
|
||||
{
|
||||
try
|
||||
{
|
||||
var key = Microsoft.Win32.Registry.CurrentUser.CreateSubKey($@"Software\Bunifu Technologies\{productType.ToString()}");
|
||||
key.SetValue("CLI", encryptedData);
|
||||
key.Close();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new Exception("Registry write failed: " + ex.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user