益友软件工作室

加密金刚锁相关技术 → 加密类技术文章 → 也谈《小商品软件的加密方法》

也谈《小商品软件的加密方法》

文章作者:胜利油田胜利石油建设技校教务处 马德刚

本报99.11.22日实用沙龙中《小商品软件的加密方法》提供了一种在Win98/95下可行有效的加密方法,但在Windows NT及以后的Windows 2000(NT内核)中是行不通的。因为在NT内核下不支持DOS程序直接访问低层硬件,这里笔者提供一种更好的加密方法——磁盘序列号加密法。

在微软的操作系统中,硬盘的磁盘序列号是在硬盘分区后系统产生的8字节随机数字,理论上有重复的可能,但实际上找到两个相同的分区序列号很难,因此,在实际应用中可以把硬盘序列号作为唯一识别码用于我们的加密系统,实际应用中可以对序列号做几次逻辑运算,让别人觉得不是磁盘序列号。注意,软盘也有磁盘序列号,是在格式化后产生的,当进行磁盘复制时,两个磁盘的序列号也被复制为一样的。因此,不能利用软盘的序列号进行加密。当然,硬盘也可以用GHOST等软件克隆,但是为了使用某个软件而去克隆整个硬盘的情况是极少发生的。

下面代码是一个C动态连接库,在Windows98/95/NT4.0+VC5.0环境下编译通过,用于产生密码锁。

// MyDll.cpp

//产生密码锁

/

#include < windows.h >

#include < winbase.h >

#include < stdio.h >

//#include "mydll.h"

BOOL APIENTRY DllMain(HANDLE hInst, DWORD

ul_reason_being_called, LPVOID lpReserved)

{

return 1;

UNREFERENCED_PARAMETER(hInst);

UNREFERENCED_PARAMETER(ul_reason_being_called);

UNREFERENCED_PARAMETER(lpReserved);

}

///////////////////////////////////////////////////

DWORD APIENTRY GetDiskSerialNo(void)

{

LPCTSTR lpRootPathName="c:\\"; //取C盘的序列号

LPTSTR lpVolumeNameBuffer=new char[12];//磁盘卷标

DWORD nVolumeNameSize=12;

DWORD VolumeSerialNumber;//磁盘序列号

DWORD MaximumComponentLength;

LPTSTR lpFileSystemNameBuffer=new char[10];

DWORD nFileSystemNameSize=10;

DWORD FileSystemFlags;

GetVolumeInformation(lpRootPathName,

lpVolumeNameBuffer, nVolumeNameSize,

&VolumeSerialNumber, &MaximumComponentLength,

&FileSystemFlags,

lpFileSystemNameBuffer, nFileSystemNameSize);

VolumeSerialNumber^=0x90909090;//做一转换,

别让人一眼就看出是磁盘序列号

return VolumeSerialNumber;

}

DWORD APIENTRY CreateLock(void)

{

DWORD dwNo;

dwNo=GetDiskSerialNo();

dwNo^=0x90909090;

return dwNo;

}

DWORD APIENTRY TestKey(char far *sSN)

{

DWORD dwSN;

if(strlen(sSN)==0){return 0;}

sscanf(sSN,"%8lX",&dwSN);

dwSN=~dwSN;///////// 加密运算

dwSN^=0x88888888;//////////加密运算

sprintf(sSN,"%8lX",dwSN);

if (dwSN==CreateLock())return 1;

else return 0;

}

下面是解密机的源代码。因为功能简单,不用编译成Windows应用程序,做成控制台(DOS)下应用程序就可以完成任务。

//GetKey.C

//解密机,获得密匙

#include < stdio.h >

void main(void)

{

unsigned long dwSN;

printf("\n请输入密码锁号:");

scanf("%8lX",&dwSN);

dwSN=~dwSN;//////解密运算

dwSN^=0x88888888;/////////解密运算

printf("该用户的密匙是 %8lX\n",dwSN);

}

使用说明:上面的DLL随应用程序一同发行。解密机软件作者保留,千万别散发.

注册时,调用CreateLock()得到机器的识别号(密码锁),在应用程序中显示给用户, 用户得到该序列号后通知软件作者(作者一定得留下联系方法),作者根据密码锁利用解密机(见程序)得到密匙,通过网络或电话送给用户,用户根据密匙注册,注册后应用程序把密匙写进Windows注册表,以备TestKey(x)函数检测密匙用。

以后应用程序每次运行都要调用TestKey(x)函数(其中x=密匙),用于检测密匙是否正确,正确返回非零值(合法用户),程序继续运行,否则(非法用户)退出程序。

下图用VC5.0编制的一个基于对话框的简单应用程序的界面(),当输入正确的密匙,将显示”合法用户”,否则显示”非法用户”,并退出程序.因篇幅所限,源程序不再这里给出,请见谅.

这样,你的应用程序可以免费发行出去,你就坐在家里收钱吧(少收点钱,否则自有高手破解)!有点天方夜谭吗,不!得看你的程序功能如何了,发财可别忘了我的一份啊。

特别申明

本栏目的文章都是本人从网上搜集而来,仅供大家学习研究之用,请不要用于商业目的!其中署名“佚名”的,意思是作者不详。如果某些文章未署你的名字,请来信告知,我会补上的。如果你认为某些文章侵犯了你的正当权宜,也请来信,我会将它删除。