您的位置:首页 > 其它

.NET平台下基于webservice,通过获取硬件cpu序列号和随机字符串序列号实现软件加密的一种方法。

2007-08-30 15:46 1136 查看
目前的软件加密方法有很多,可以通过序列号来实现,但是只通过序列号来实现无法控制软件环境的改变,存在换个机子照样可以用的缺陷,而将序列号和物理结合起来使用可以控制用户只能在一台机器上使用。本文就是按照这样的思路实现的。原理图如下:



具体实现思路:

(1)首先创建保存序列号和cpu物理编号的数据库,建立序列号和cpu物理编号的对应关系表。

(2)编写Web Service 接口函数,接受两个字符串参数:strSerialNo和strCpuNo ,验证的原则是首先验证序列号,如果序列号匹配,则进一步比较cpu编号,如果是第一次验证,只要序列号匹配则认为验证通过,返回为true;如果不是第一次验证,则检验cpu编号,匹配则返回true,反之false;如果序列号不对,直接返回false;

(3)编写客户端验证函数,从配置文件中读取序列号,调用GetCpuSerialNo()获取cpu编号,然后调用web service方法进行验证。获取cpu物理编号主要是通过调用WMI接口函数来实现。

String ^CWebServiceData::GetCpuSerialNo()
{
String ^ strCpuNo;
try
{
ManagementObjectSearcher ^mos = gcnew ManagementObjectSearcher("select * from Win32_Processor");
ManagementObjectCollection^ moc = mos->Get();
if(moc->Count==0)
{
return "";
}

ManagementObjectCollection::ManagementObjectEnumerator ^mocEnumerator =moc->GetEnumerator();
while(mocEnumerator->MoveNext())
{
ManagementObject ^mo = (ManagementObject ^)mocEnumerator->Current;
strCpuNo = mo["ProcessorId"]->ToString();
break;
}

return strCpuNo;
}
catch(Exception^ e)
{
System::Windows::Forms::MessageBox::Show(e->Message);
return "";
}
}

(4)考虑到网络环境的影响,在网络不稳定的情况下,可以通过注册表来记录验证状态,只要第一次验证通过,则以后的验证中,在网络不通的情况下,则访问注册表的相应的状态项,若曾经验证通过则通过,若没有验证成功过,则验证失败。

验证程序实现如下:

bool CWebServiceData::GetCheckStatus()
{
//访问注册表
RegistryKey ^ hklocalmachine;
RegistryKey ^ hksoftware;
RegistryKey ^ hkeuroagps;
try
{
hklocalmachine = Registry::LocalMachine;
hksoftware = hklocalmachine->OpenSubKey("SOFTWARE",true);
hkeuroagps = hksoftware->OpenSubKey("EUROAGPS",true);
if(!hkeuroagps)
{
hkeuroagps = hksoftware->CreateSubKey("EUROAGPS");
}
Object^ isvalid = hkeuroagps->GetValue("isvalid");
if(!isvalid)
{
hkeuroagps->SetValue("isvalid",0,RegistryValueKind::String);
}
}
catch(Exception ^ e)
{
Windows::Forms::MessageBox::Show(e->Message);
return false;
}
//获取并验证序列号和Cpu序列号
String ^ strSerialNo = GetSerialNo();
if(strSerialNo=="")
{
return false;
}
String ^strCpuSerialNo = GetCpuSerialNo();
if(strCpuSerialNo=="")
{
System::Windows::Forms::MessageBox::Show("Cpu序列号信息无法获取");
return false;
}
try
{

//判断当前网络环境下能够访问webservice 接口函数:
HttpWebRequest ^myHttpWebRequest = dynamic_cast<HttpWebRequest^>(WebRequest::Create("http://192.168.126.58/CheckUserRight/CheckUserRight.asmx"));
if(myHttpWebRequest->GetResponse())
{
CheckUserRightClass objCheck;
bool isvalid = objCheck.CheckUserRight(strSerialNo,strCpuSerialNo);
if(!isvalid)
{
Windows::Forms::MessageBox::Show("非法使用,请与软件供应商联系!!");
return false;
}
//验证成功,则保存注册状态到注册表
else
{
hkeuroagps->SetValue("isvalid",1,RegistryValueKind::String);
return true;
}
}
else
{
if(hkeuroagps->GetValue("isvalid")!="1")
{
Windows::Forms::MessageBox::Show("非法使用,请与软件供应商联系!!");
return false;
}
}
return true;

}

//无法访问时抛出WebException 异常
catch(WebException ^e)
{
e->Message;
if(hkeuroagps->GetValue("isvalid")!="1")
{
Windows::Forms::MessageBox::Show("非法使用,请与软件供应商联系!!");
return false;
}
return true;
}
catch(Exception ^e)
{
System::Windows::Forms::MessageBox::Show(e->Message);
return false;
}
}

(5)存在的问题:

我在测试的时候发现,目前获取硬件编号的方法很多,可以获取硬盘的编号,主板的序列号,网卡mac地址等,但是各种方法都存在缺陷,硬盘和主板序列号都存在杂牌的情况下无法获取的问题,网卡mac地址在多网卡的情况下获取不稳定问题,综合考察各种方法,还是cpu序列号最安全,但是也不是最安全的,因为同一个厂商同一个批次的序列号是一样的。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐