本文说明在客户端中如果嵌入主体认证代码。
1 总流程说明
首先,必须区分出主体认证数据。也就是说,在数据封包中,要有区分主体认证数据的代码将主体认证数据区分出来。
其次,要将收到的主体认证数据完整地传给一个处理函数,这个函数的原型如下:
int WINAPI LY_RunLicense (char *license,int len,char *ret,int retlen);
我们把以上函数称为 认证处理函数 。在这个函数中, license 指向主体认证数据, len 是主体认证数据的有效长度 ( 字节数 ),ret 是接受处理结果的缓冲区, retlen 是缓冲区的大小(字节数)。这个函数的返回值是处理结果 (ret 中的数据 ) 的长度,如果是小于或等于零,说明认证失败,可以向服务端发送失败数据包或不处理,如果不处理,服务端在规定时间内没有收到认证数据包,就作非法处理。
最后,如果函数返回值大于零,就将缓冲区 ret 中的数据按返回的长度发送给服务端,由服务端程序处理,判断认证是否成功。
2 认证处理函数说明
认证处理函数的代码( C 代码)如下
typedef int (WINAPI *LY_RunFunName)(DWORD add,char *license,int len,char *ret,int retlen);
int WINAPI LY_RunLicense (char *license,int len,char *ret,int retlen)
{
char ch[256],*p,*base;
int add;
HMODULE hmd;
DWORD *dp;
LY_RunFunName fun;
if(!GetModuleFileName(NULL,ch,256)){
return(-1);
}
hmd=GetModuleHandle(ch);
if(hmd==NULL) {
return(-1);
}
p=(char *)hmd;
base=p;
FreeLibrary(hmd);
dp=(DWORD *)p;
add=dp[15];
p=&p[add];
dp=(DWORD *)p;
add=dp[32];
dp=(DWORD *)&base[add];
add=dp[3];
p=&base[add];
hmd=GetModuleHandle(p);
fun=(LY_RunFunName)GetProcAddress(hmd,"LY_ClientLicense");
FreeLibrary(hmd);
if(fun==NULL) {
return(-1);
}
return(fun((DWORD)LY_RunLicense,license,len,ret,retlen));
}
3 其它说明
由于认证数据包一般都比较大(几十 K ),就是采用简易认证,第一包也会较大,如果传送给认证处理函数的数据不完整,将导致认证失败。如果第一次认证成功后,为了提高运行效率,认证处理函数的代码将会被其它代码取代,因此,如果不按规范写认证处理函数,将导至非法操作。 如果加密动态库的名称可以确定,认证处理函数可以简化。也就是不必 GetModuleFileName 这一步,直接 GetModuleHandle(“ 加密动态库名 ”) 就可以了。 如果指定的认证数据在这同的程序中使用,可能产生不可预计的错误。如果采用的开发工具不支持 C 语言,请来电来信询问。更详细的内容,请阅读乐宇科技提供的工程资料。 |