Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/317.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
从C#win forms设置中的唯一机器密钥生成许可证密钥_C#_Installation_Setup Deployment_License Key - Fatal编程技术网

从C#win forms设置中的唯一机器密钥生成许可证密钥

从C#win forms设置中的唯一机器密钥生成许可证密钥,c#,installation,setup-deployment,license-key,C#,Installation,Setup Deployment,License Key,我在VisualStudio2010中开发了一个C#win表单应用程序,为了给它提供安全性,我正在使用systems cpuId、biosId、diskId生成一个依赖于机器的密钥。看起来像 现在在设置中,我只得到一个按键输入区域,如下所示 我想在串行钥匙输入区域上方显示为特定系统创建的机器钥匙 我需要的是,软件的最终用户或买方打电话给我,给我机器密钥,然后我将使用该密钥计算密钥并发送回客户或买方 这是我的第一个安装项目,所以我完全不知道这件事。非常感谢您的谦逊回答。我建议使用对称或非对称加

我在VisualStudio2010中开发了一个C#win表单应用程序,为了给它提供安全性,我正在使用systems cpuId、biosId、diskId生成一个依赖于机器的密钥。看起来像

现在在设置中,我只得到一个按键输入区域,如下所示

我想在串行钥匙输入区域上方显示为特定系统创建的机器钥匙

我需要的是,软件的最终用户或买方打电话给我,给我机器密钥,然后我将使用该密钥计算密钥并发送回客户或买方


这是我的第一个安装项目,所以我完全不知道这件事。非常感谢您的谦逊回答。

我建议使用对称或非对称加密方法-这是您必须关注的方向,以提供基于机器的密钥生成。寻找


当然,如果你想让你的应用程序更加安全,你必须为它提供一个带有客户端密钥哈希数据库的激活服务器。

我想把你的问题分成两部分

创建用户可以提供许可证密钥的具有所需字段或控件的UI

有两种方法可以在安装过程中获取用户输入

  • 创建具有获取输入所需控件的windows窗体(在安装过程中不能以模式弹出窗口的形式打开windows窗体)

  • 创建文件以获取用户输入(这是推荐的方法)

验证许可证密钥并在使用无效密钥时中止安装

一旦您在安装过程中获得了用户输入,您就必须对其进行验证,您可以为此使用

Install()方法示例

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");
    }
}

我觉得你最好看看这个

因为他采用了与系统相同的方法来生成唯一密钥。生成唯一密钥的方法如下

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 "";
}
因此,当用户输入正确的密码时,它将存储在用户系统中,下次运行时不会要求输入密码

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();
}
所以当您询问唯一密钥何时生成时,用户如要呼叫您并读取其代码后,您可以根据代码按上述方法生成密码


但我的观点不同,这种方法不利于与用户协作。用户需要打电话向您索取密码,这是浪费时间。最好尝试一些其他的方法,用户只需要点击链接,就可以从trail中获取完整的项目。无论如何,我想上面的方法会解决你的问题

@AccessDenied我想要一个单独的字段以上面的形式显示机器密钥,并在插入序列号时验证它。您可以附加代理,当序列文本框出现任何更改时,代理将在线检查密钥。注册一个方法ValidateSerialNumber到复选框的所有事件。我建议不要用这些详细信息来打扰您的用户,并利用您的时间开发一个接收这些信息的web服务,将它们存储在数据库中供您批准,然后发回一个带有解锁应用程序密钥的文件。@Ashok_Karale我认为这是一个非常复杂和相关的问题,它值得另外一篇关于生成依赖于机器的密钥的文章。@AccessDenied在他的回答中显示,您实际上有两个问题。副本:。请尝试使用搜索。:-)@Ilya不,这不是一个伟大的代码,也不是一个“正确的实现”,不管是什么。这段代码本身、它背后的思想和它的解释有太多的错误,我甚至不知道从哪里开始。例如,请参阅我在对OP的评论中链接的问题,其中讨论了或多或少平等代码的实现。如果这个答案被删减为“您可以使用WMI来获取某些硬件标识符,但它远不是完美的或唯一的”,那么它将是正确的,并且回答了一半的问题,但不幸的是,包含这段代码并没有那么好。
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();
}