从C#win forms设置中的唯一机器密钥生成许可证密钥
我在VisualStudio2010中开发了一个C#win表单应用程序,为了给它提供安全性,我正在使用systems cpuId、biosId、diskId生成一个依赖于机器的密钥。看起来像 现在在设置中,我只得到一个按键输入区域,如下所示 我想在串行钥匙输入区域上方显示为特定系统创建的机器钥匙 我需要的是,软件的最终用户或买方打电话给我,给我机器密钥,然后我将使用该密钥计算密钥并发送回客户或买方从C#win forms设置中的唯一机器密钥生成许可证密钥,c#,installation,setup-deployment,license-key,C#,Installation,Setup Deployment,License Key,我在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();
}