Generate the license key from the unique machine key in C# win forms Setup
Asked Answered
T

3

8

I have developed an C# win forms application in Visual Studio 2010 and to provide security to it I am generating a machine dependent key by using systems cpuId, biosId, diskId. It looks like

key

Now in Setup I am just getting one key input area like below.

enter image description here

and I want to show the machine key which is created for the specific system, above the serial key input area.

My need is that the end user or buyer of the Software call me and give me the machine key and then I will calculate a key using that key and send back to client or buyer.

This is my first setup project so I am totally unaware of this thing. I will really appreciate your humble response.

Third answered 27/12, 2013 at 10:12 Comment(7)
@AccessDenied I want a separate field to show machine key in above form and validate it while inserting Serial numberThird
You can attach delegate which will check the key on-line when any change in serial textboxes appear. Register one method ValidateSerialNumber to all events of checkboxes.Hobbism
I suggest to not bother your user with these details and use your time to develop a web service that receives these info, store them in a database for your approval and send back a file with the key to unlock the application.Doubledealing
I don't want to check it online. My client might don't have active internet connection and also security purpose I am going to activate the software by phone call verificationThird
@Ashok_Karale I think it is quite complex and relevant question that it deserves a separate article about generating secret machine-dependent keyApogee
@IlyaTereschuk agree with you. I almost searched every where on web but not getting the perfect answer. Once we have answer here surly I will post in detail article on this to help every one.Third
As @AccessDenied shows in his answer, you actually have two questions. Duplicates: How to add additional custom window to VS setup projects UI flow, How to fast get Hardware-ID in C#?, Reliable way of generating unique hardware ID. Please try to use the search. :-)Selangor
P
4

I like to break your question into two parts

Creating a UI with required fields or controls where user can provide the license key

There are two way to get the user input during the installation,

  • Creating a windows form with required controls to get the input(You can not open windows form as a modal pop up during the installation)

  • Creating a .wid file to get the user input(This would be the recommended approach)

Validating the license Key and aborting the installation when invalid key is used

Once you have got the user input during the installation you have to validate it, You can use Installer Class for this.

Install() method example

public override void Install(System.Collections.IDictionary stateSaver)
{
    //Invoke the base class method
    base.Install(stateSaver);

    if (!keyEnteredByUser.Equals(generatedKey))
    {
       //This would abort the installation
       throw new Exception("Invalid Key");
    }
}
Papua answered 27/12, 2013 at 10:41 Comment(0)
K
1

I think better you should take look in this Article.

In that he have taken the same way to generating the unique key as per the system. And the way to generate the unique key is follows.

public static string GetSystemInfo(string SoftwareName)
{
 if (UseProcessorID == true)

    SoftwareName += RunQuery("Processor", "ProcessorId");

if (UseBaseBoardProduct == true)

    SoftwareName += RunQuery("BaseBoard", "Product");

if (UseBaseBoardManufacturer == true)

    SoftwareName += RunQuery("BaseBoard", "Manufacturer");
// See more in source code

SoftwareName = RemoveUseLess(SoftwareName);

if (SoftwareName.Length < 25)

    return GetSystemInfo(SoftwareName);
return SoftwareName.Substring(0, 25).ToUpper();
}

private static string RunQuery(string TableName, string MethodName)
{
ManagementObjectSearcher MOS =
                 new ManagementObjectSearcher("Select * from Win32_" + TableName);
foreach (ManagementObject MO in MOS.Get())
{
    try
    {
        return MO[MethodName].ToString();
    }
    catch (Exception e)
    {
        System.Windows.Forms.MessageBox.Show(e.Message);
    }
}
return "";
}

And following method which describes how to generate the password code which matches the unique key ,

static public string MakePassword(string st, string Identifier)
{
if (Identifier.Length != 3)
    throw new ArgumentException("Identifier must be 3 character length");
int[] num = new int[3];
num[0] = Convert.ToInt32(Identifier[0].ToString(), 10);
num[1] = Convert.ToInt32(Identifier[1].ToString(), 10);
num[2] = Convert.ToInt32(Identifier[2].ToString(), 10);
st = Boring(st);
st = InverseByBase(st, num[0]);
st = InverseByBase(st, num[1]);
st = InverseByBase(st, num[2]);

StringBuilder SB = new StringBuilder();
foreach (char ch in st)
{
    SB.Append(ChangeChar(ch, num));
}
return SB.ToString();
} 

So when the user enters the correct password it will be stored in the user system and the next run it wont ask for the password.

public static void WriteFile(string FilePath, string Data)
{
FileStream fout = new FileStream(FilePath, FileMode.OpenOrCreate,
  FileAccess.Write);
TripleDES tdes = new TripleDESCryptoServiceProvider();
CryptoStream cs = new CryptoStream(fout, tdes.CreateEncryptor(key, iv),
   CryptoStreamMode.Write);
byte[] d = Encoding.ASCII.GetBytes(Data);

cs.Write(d, 0, d.Length);
cs.WriteByte(0);

cs.Close();
fout.Close();
}

So as you asked when the unique key generated , the user as to call you and read his code after based on the code you can generate the password as by above method .

But my point of view is different, this method is not good to collaborate with user. Its waste of time that user needs to call you for password. Better try some other method where user just need to click the link which makes project as full from trail. Anyway the above method will solve your question, I guess.

Karrah answered 27/12, 2013 at 10:47 Comment(1)
@Ilya no, that is not great code nor anywhere close to a "right implementation", whatever that may be. There is so much wrong with this code itself, the idea behind it and its explanation that I don't even know where to start. See for example the questions I linked in my comment to OP, where the implementation of more or less equal code is discussed. If this answer were trimmed down to "You can use WMI to get certain hardware identifiers, but it's far from perfect or unique" it would be correct and answering half the question, but by including this code it is unfortunately not that good.Selangor
A
0

I suggest using an approach of symmetric or asymmetric encryption - that is direction you must look in to provide machine-based secret key generation. Look for its model in .NET.

Of course, if you want your application to be much more secured, you'll have to provide an activation server for it with client keyhashes database.

Apogee answered 27/12, 2013 at 10:22 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.