C#下一机一码注册方式的实现

对于做共享软件开发的程序员来说,最让大家头痛的就是辛辛苦苦写出的软件,本想拿来换口饭吃,可刚刚发布到网上就被那些共享主义者(其实业没什么不好或不对,本人就属于这类人,嘿嘿)将序列号和注册机免费发放到网上,最终导致开发者只能眼睁睁看着束手无策。但与此同时部分软件开发者也开始了反任意爆破等方法的研究,于是现在网上就出现了各种各样的注册方式,但目前看最有效的就属于一机一码这种方式了。

可能因为这种方式最有效,所以微软就在它新推出的编程平台上提供了一些简单实用的方法,今天本人就借助.NET平台下的公共类库来实现一机一码注册算法。在此之前先来介绍一下一机一码的注册原理及与一码一序列号的比较。

之所以是一机指的就是通过获取机器硬件(主要是硬盘和CPU)的一些信息作为注册序列号的一部分,因为目前世界上所有厂家生产的每个硬盘和每个CPU都有自己独有的一些ID号等硬件信息(理论上是如此但实际上也许有一样的,不过那种几率很低,予以忽略不计了),通过一定算法将这些硬件信息读取出来作为注册码,这样就免除了不同机器可以使用相同注册序列号的问题,一码一序列号就是因为这样才造成了只要一个有注册码和序列号被发布到网上别人就可以正常使用软件这种一码通用的现象。

由于.NET提供了相关的类库,本人又稍微借鉴下网上的资料及本人只从事C#方面开发,所以在此本人只写了C# 的代码,下面就把代码写在下面了:

         private string CpuId()

         {

              try

              {

ManagementObjectCollection collection1 = new ManagementClass("Win32_Processor").GetInstances();

                   string strCpuID = null;

                   foreach (ManagementObject obj1 in collection1)

                   {

                       strCpuID = obj1.Properties["ProcessorId"].Value.ToString();

                       break;

                   }

                   return strCpuID;

              }

              catch

              {

                   return "strCpuID";

              }

         }



         //硬盘序列号读取函数

         private string DiskId()

         {

              try

              {

ManagementObjectSearcher searcher = new ManagementObjectSearcher("SELECT * FROM Win32_PhysicalMedia");

                   String strHardDiskID = null ;

                   foreach(ManagementObject mo in searcher.Get())

                   {   

                       strHardDiskID = mo["SerialNumber"].ToString().Trim();

                       break;         

                   }

                   return strHardDiskID;

              }

              catch

              {

                   return "strHardDiskID";

              }

     }

以上只完成了全部算法的一部分,接下来就是记录注册信息,这个一般都是记录在系统注册表中,这就涉及到注册表的读写,实际并不复杂,这里将读写注册表的代码也写下来了:

//读取注册表注册信息

RegistryKey softwareKey = Registry.LocalMachine.OpenSubKey("SOFTWARE");

RegistryKey choseKey = softwareKey.OpenSubKey("SOW");

RegistryKey SowKey = choseKey.OpenSubKey("Regexample");

this.textBox2.Text = SowKey.GetValue("SerialId").ToString();

this.textBox1.Text = SowKey.GetValue("RegisterCode").ToString();

//写入注册表注册信息

RegistryKey softwareKey = Registry.LocalMachine.OpenSubKey("SOFTWARE",true);

RegistryKey choseKey = softwareKey.CreateSubKey("SOW");

RegistryKey ValueKey = choseKey.CreateSubKey("Regexample");

ValueKey.SetValue("SerialId", SerialId().ToString());

ValueKey.SetValue("RegisterCode", this.textBox1.Text);

注:实际注册表读写信息:

[HKEY_LOCAL_MACHINE\SOFTWARE\SOW\Regexample]

"SerialId"="-1587187206"

"RegisterCode"="-1587187206"

  通过以上两个步骤基本的实现代码就基本完成了,接下来是具体实现顺序,当软件运行时,将先从注册表获取注册信息,来比较经过某种算法处理过的注册码和序列号是否相同,如注册表不存在所要信息就在注册表中写入未注册信息,之后获取机器硬件(硬盘和CPU)信息,将其哈希代码作为注册序列号返回并写入注册表。这样一来在软件下次启动时,就可以直接从注册表获取注册信息来比较而不必重新读取硬件ID信息了(因为偶发现.NET读取硬件信息的速度是很慢的。。。。。。。)。

  大体的实现方式就是这样,本人以将一个完整的演示程序(含源码)放到本人共享空间的.NET相关目录下,有兴趣的可以去看看,但这里还要提醒大家一下,这个方法还存在3个问题:其一,由于.NET自身的可反编译性(阴谋啊,阴谋,绝对是微软的阴谋,刚刚看完《欢迎加入NHK》的某人飘过),致使所有在.NET噢那个框架开发出来的程序都可以被反编译成源代码,即使做怎样复杂的注册算法都将失去实际意义(即使利用混淆起到的作用也不大,毕竟不是研究密码学的,注册算法不可能复杂到那种地步);其二,即使不被反编译但由于采用常规IF判断方式,给破解者留下了可设跳转断点的弱点,导致软件易被爆破掉;其三,由于最初想让软件启动速度变快,导致获取硬件信息仅在注册表没有相关信息的情况下才执行,造成可以伪造注册信息,这里实际应改动下的。不过,目前这些问题本人已基本解决了,并且有些还有进一步改进。希望大家在使用这种方法时自己再改动下(当然,由于微软下一代软件的理念是WEB与WINFORM的合二为一,所以这种注册方式是可以用在WEB项目的注册上的),这里就权当抛砖引玉了,由于偶是程序开发新手加之写的都是些没啥技术含量的东西所以就不在这里卖弄了,还望高手来指点,谢谢。

你可能感兴趣的:(C++,c,算法,C#,WinForm)