请高手帮下忙,!怎样利用硬盘号给软件加密.

我想给已有的EXE软件二次封装,顺便用硬盘号(机器码)加密不知道怎么解决请各位帮忙,谢谢!(主要是控制只能在一台机器上安装)还有好的方法或软件请各位推荐下,谢谢!
谢谢楼下帮忙!!我是个菜鸟不懂的编程,,
希望能有机器码生成器或 类似的软件。或方法给现在的 程序加密,
谢谢!!!希望能够帮助!!

第1个回答  2006-06-02
大家知道,每当我们格式化软盘或硬盘时系统都会给它分配一个序列号,即用DOS命令dir显示出的"Volume Serial Number is 0A41-0E0A"。该序列号是随机产生的,且具有唯一性。也就是因为这个原因许多软件的测试版本利用该项技术使测试版一旦过了限定期限就不能再使用,即使将该软件重新安装也无济于事。另外,有些共享软件的注册码也是通过这个序列号来生成的。同样的方法我们也可以运用到软件的防拷贝技术。那么如何才能实现上述功能呢?

为了达到目的我们必须首先能够得到硬盘的序列号,其次,为了安全起见我们最好再选择一种加密算法,将加密后的硬盘的序列号作为密文公开存放,软件通过解密得到明文,即硬盘的序列号,通过将解密后的硬盘序列号和实际的硬盘序列号相比较得出程序是否合法。这一步当然是由应用程序秘密运行,用户根本不知道,从而达到软件的二次加密目的,同时也隐藏了软件的合法性识别过程,使破译者无从下手。下面就来谈谈如何具体实现。

一、如何读取硬盘序列号

要读取硬盘序列号我们可以用汇编来实现,但毕竟不容易,况且也不能有效的结合到PB脚本中。在PB中我们可以通过调用Windows提供的外部函数GetVolumeInformationA()来实现。这相对来说比较简单。

该函数的原型为:
BOOL GetVolumeInformation(
LPCTSTR lpRootPathName,
LPTSTR lpVolumeNameBuffer,
DWORD nVolumeNameSize,
LPDWORD lpVolumeSerialNumber,
LPDWORD lpMaximumComponentLength,
LPDWORD lpFileSystemFlags,
LPTSTR lpFileSystemNameBuffer,
DWORD nFileSystemNameSize

上述原型中,参数类型只要是以"LP-"开头的表明该参数用的是长指针(Long Pointer)类型,即在PB中调用时的参数传递是通过引用传递。在8个参数中对我们真正有用的只有两个LPCTSTR lpRootPathName和LPDWORD lpVolumeSerialNumber。其中参数lpRootPathName是指向文件系统根目录的地址,我们需要用它来指明所要获取序列号的硬盘盘符;参数lpVolumeSerialNumber是返回的硬盘序列号的地址,这正是我们需要的。

众所周知,PB在调用任何外部函数前都要首先进行函数声明,可以将声明放在全局或局部函数声明中。具体声明如下:

Function Boolean GetVolumeInformationA( &
ref String ls_Rootpath, &
ref String ls_volumnename, &
Ulong lul_VolumeNameSize, ref Ulong lul_VolumeSerialNumber, &
ref Ulong lul_MaximumComponentLength, &
ref Ulong lul_FileSystemFlags, &
ref String ls_FileSystemNameBuffer, &
Ulong lul_FileSystemNameSize &
) Library "Kernel32.dll"

上述声明中,"ref"指明是该参数是通过引用传递的,有关函数引用的详细内容请参见有关教程。声明完毕我们不能马上进行调用,还必需确保已为它分配足够的内存空间,即使是参数引用传递也是这样,否则的话将会出现调用错误,这跟C语言的引用调用不同,这一点往往被忽视,希望读者能够注意。也就是为什么我在调用该函数前将有些字符串参数给它预先分配了多达256个字符空间以及给一些整型类型的参数赋初始值256。完整的读取硬盘序列号的程序代码如下:

/******************* 程序代码 ************************/

String ls_Rootpath, ls_volumnename
ls_Rootpath = "C:" // 指定要得到序列号的硬盘,

// 一般情况都是C盘,除非你能保证用户存在其它逻辑盘或物理盘

ls_volumnename = Space(256) // 分配足够的空间,下同
Ulong lul_VolumeNameSize
lul_VolumeNameSize = 256
Ulong lul_VolumeSerialNumber, lul_MaximumComponentLength, lul_FileSystemFlags

lul_MaximumComponentLength = 256
String ls_FileSystemNameBuffer
ls_FileSystemNameBuffer = space(256)
Ulong lul_FileSystemNameSize
lul_FileSystemNameSize = 256
beep(1)
boolean lb_rtn
lb_rtn = False
lb_rtn = GetVolumeInformationA(ls_Rootpath, ls_volumnename, lul_VolumeNameSize,
lul_VolumeSerialNumber, lul_MaximumComponentLength, lul_FileSystemFlags,
ls_FileSystemNameBuffer, lul_FileSystemNameSize)
if lb_rtn = true then
MessageBox("提示","函数调用成功!")
else
MessageBox("提示","函数调用失败!")
end if
sle_1.text = String(lul_VolumeSerialNumber) // 得到硬盘序列号

/********************* 结束 *************************/

一旦读取成功我们的任务也就完成了近一半,接下来要做的是怎样选择一个合适的加密算法。

二、选取一个优秀的加密算法

1、数据加密概述

早在几千年前人类就已经有了通信保密的思想和方法。但直到1949年,信息论创始人香农发表著名文章,论证了一般经典加密方法得到的密文几乎都是可破译的。密码学才得以进入了一个新的发展时期。70年代后期,美国的数据加密标准DES和公开密钥密码体制的出现成为近代密码学发展史上的两个重要里程碑。

公开密钥密码体制的概念是由Difie与Hellman于1976年提出。所谓公开密钥密码体制就是加密密钥与解密密钥不同,是一种由已知加密密钥推导出解密密钥在计算上是不可行的密码体制。其中,基于数论中大数分解问题的RSA体制曾被ISO/TC97的数据加密技术委员会SC20推荐为公开密钥数据加密标准。

2、RSA体制的基本原理

该体制是根据寻求两个大素数比较简单,而将它们的乘积分解开则极其困难这一原理来设计的。在已提出的公开密钥算法中它是最容易理解和实现的。RSA在世界上许多地方已成事实上的标准。ISO几乎(但没有明确)已指定RSA用作数字签名标准。该算法已经经受住了多年深入的密码分析,虽然密码分析者既不能证明也不能否定RSA的安全性,但这恰恰说明了该算法有一定的可信度。它的安全性是与大数分解密切相关的。我想通过下表你将会对它的安全性有一个较好的认识,它给出了在计算机每一微妙做一次操作的假定下分解不同大小的N所需要的时间。

N的十进位数 50 75 100 200

时间 3.9小时 104天 74年 3.8X1015年

RSA加密算法具体如下:

(1)选取两个大素数,p和q。为了获得最大程序的安全性,两个素数的长度一样。并计算乘积N(N=pq)。
  (2) 随后计算出N的欧拉函数ф(N)=(p-1)(q-1),ф(N)定义为不超过N并与N互素的数的个数。
  (3)从[0,ф(N)- 1]中随机选取加密密钥e,使得e和ф(N)互为素数。   
(4)计算出满足公式ed=1 modф(N)的d,d为解密密钥。   
(5)若用整数X表示明文,整数Y表示密文(X,Y均小于N),则加解密运算为:

加密:Y = Xe mod N   
解密:X = Yd mod N   
注意,其中的d和N也互素。e和N是公开密钥,d是秘密密钥。两个素数p和q应舍弃,但千万不要泄密哦。

3、相关数学背景知识
(1)素数:素数是一个比1大,其因子只有1和它本身,没有其它数可以整除它的数。素数是无限的。例如,2,3,5,7……等。
  (2)两个数互为素数:指的是它们除了1之外没有共同的因子。也可以说这两个数的最大公因子是1。例如,4和9,13和27等。
  (3)模变换:两个数相模,如A模N运算,它给出了A的余数,余数是从0到N-1的某个整数,这种运算称为模运算。

4、算法的具体实现
从RSA的基本原理我们得知,对明文进行加密选择一个合适的e很重要,如果你选择合适的话,RSA的加密速度将快得多,并且也不会因为用户机器的限制而要做更多的变换(指在计算中为了避免数据的溢出所进行的转换,毕竟我们用的是PC机再说也用不着很高的安全性)。最常用的三个e值是3,17,65537。在这里我们取的e等于3,当然到底选取哪个e值并没有规定,这里只是为了演示方便罢了。

根据算法定义,

(1)为了方便起见我们选取素数p = 3和q = 11,则N = pq = 3 * 11 = 33。   

(2)ф(N)=(p-1)(q-1)= 2 * 10 = 20。   

(3)从[0,ф(N) - 1]中,即,[0, 19]之间任意选取加密密钥e = 3,且e和ф(N)互素。

(4)如何从公式ed=1 modф(N)求出解密密钥d?

由模的定理我们可以将公式ed=1 modф(N)转换成形式ed= k * ф(N)+ 1,即3d = k * 20 + 1,将0,1,2,3…依次代入k,求出d。取k = 1,得d = 7。

读者可以通过编程实现随机选取p和q来求出相应的N,e,d。

(5)进行加解密。

对明文进行加密

根据定义,我们首先要根据N的值对明文进行分组,每个分组的值应小于N。如果要加密固定的消息分组,那么可以在它的左边填充一些0(零)并确保该值比N小。例如,我们要对数据X=172035594进行加密(在我的计算机上C盘的序列号是0A41-0E0A,转换成十进制就是172035594),我们首先要将它分成小于N(N=33)的若干小组。可以分成,X1=17,X2=20,X3=3,X4=5,X5=5,X6=9,X7=4。对第一分组X1运用加密公式得到加密密文Y1=X1e mod N = 173 mod 33 = 29,依次将其余分组进行加密得到,Y2=14,Y3=27,Y4=26,Y5=26,Y6=3,Y7=31。即密文Y= 2914272626331。我们可以将密文存储在文件或注册表中,每当应用程序启动时先读取密文,并将其解密,再将解密后的结果与硬盘序列号进行比较,以此来判断软件是否合法。在实际运用中我们可以随时通过程序修改密文,比如,将密文去掉一位或将密文颠倒等,就可以实现诸如测试版软件的使用限制问题,

对密文进行解密

对密文进行解密同样要首先对密文进行分组,使每个分组都小于N。将密文Y=2914272626331分组成:

Y1=29,Y2=14,Y3=27,Y4=26,Y5=26,Y6=3,Y7=31

这时我们一定要注意,不要急于将将各分组代入解密公式X=Yd mod N,如果这样做了我们所得到的明文将是X=1202811913,并不是加密时的明文!是不是加密算法有错?绝对不是。回顾加解密的公式,我们不难发现它们做的都是先将一个数进行n次方运算然后在做模运算。问题就出在"n次方运算"上,千万不要忽略PowerBuilder中数值的取值范围,在其它的编程语言中也是如此。在本例中我给明文和密文用的都是unsigned long类型,它的32位所允许最大值是4294967295,的确很大,但我们不能保证一个数在进行了7次方后不超过该最大值。其实,这种情况在对明文加密时也是会发生的,只是33的3次方是35937,远小于最大值,我们将其忽略罢了。

好在问题并不像我们想象的那么复杂。由模的运算规律得知,模运算像普通的运算一样,它是可交换的、可结合的、可分配的。而且,简化运算每一个中间结果的模n运算,其作用与先进行全部运算,然后再简化模n运算是一样的。比如,

(A * B) mod N = ((A mod N) * (B mod N)) mod N。

因此,

X = Y7 mod N

= (Y3 * Y4)mod N

= ((Y3 mod N)*(Y4 mod N))mod N

当然,我们也可以将Y7分解成更多项的乘积。将分组后的密文Y1至Y7依次代入上式得出密文为X = 17 20 3 5 5 9 4。即为正确明文,解密成功。

在实际的运用中考虑到PB没有现成的乘方运算函数,为了便于读者理解原程序是如何实现RSA加密算法的本文所采用的方法是通过FOR…NEXT语句循环来实现乘方运算,读者可以将其做成一个函数,在使用的时候调用。RSA加解密算法的完整程序代码如下:

/**************** 加密程序代码 ***************/

// 以下参数由RSA加密算法得来
integer li_e, li_d, li_n 、
li_e = 3 // 设置指数e,加密密钥
li_d = 7 // 设置指数d,解密密钥
li_n = 33 // 设置N:两个素数得乘积
string ls_str
ls_str = Trim(sle_1.text) // 将明文转换成字符串,以便随后进行分组
ulong lul_temp
lul_temp = 0
ulong lul_x, lul_y // lul_x: 加密明文; lul_y: 加密密文
int I
do until ls_str = ""
lul_temp = Integer(left(ls_str, 2))
if lul_temp >= li_n then // 将明文分组,且每组均小于N(N=33)
lul_temp = Integer(left(ls_str, 1))
ls_str = right(ls_str, len(ls_str)-1)
else
ls_str = right(ls_str, len(ls_str)-2)
end if
lul_y = 1
for I = 1 to li_e // 进行乘方运算
lul_y = lul_y * lul_temp
next
lul_y = mod( lul_y, 33) // 根据加密公式计算密文
sle_2.text = trim(sle_2.text) + string(lul_y) // sle_2.tex中存放的是加密后的密文

loop

/******************** 结束 *****************/

/**************** 解密程序代码 ***************/

ls_str = Trim(sle_2.text) // 与加密同理,将密文转换成字符串,以便随后进行分组
ulong lul_x0, lul_x1
do until ls_str = ""
lul_temp = Integer(left(ls_str, 2))
if lul_temp >= li_n then // 将密文分组,且每组均小于N(N=33)
lul_temp = Integer(left(ls_str, 1))
ls_str = right(ls_str, len(ls_str)-1)
else
ls_str = right(ls_str, len(ls_str)-2)
end if

// 由于考虑到乘方运算得结果可能会超出数值所允许得最大取值,
// 因此对解密公式进行适当转换,lul_x = lul_x0 * lul_x1

lul_x0 = 1
lul_x1 = 1

// 假如解密密钥是7,则先进行数的4次方运算取模,在进行数的3次方运算取模
for I = 1 to 4
lul_x0 = lul_x0 * lul_temp
next
lul_x0 = mod( lul_x0, 33)
for I = 1 to li_d - 4
lul_x1 = lul_x1 * lul_temp
next
lul_x1 = mod( lul_x1, 33)
lul_x = mod(lul_x0 * lul_x1, 33) // 根据解密公式计算明文
sle_3.text = trim(sle_3.text) + string(lul_x) // sle_3.tex中存放的是解密后的明文

loop

/******************** 结束 *****************/

总结,文中所提供的程序代码已经在PowerBuilder 7.0,Windows 98环境下运行通过。本文所讨论的通过读取硬盘序列号方法来实现程序加密技术同样可以运用到其它程序语言中,只是具体的实现方法略有差异罢了。由于本人水平有限,错误和不足之处再所难免,因此还敬请同行们给予指教。
第2个回答  2006-06-02
对啊。希望大侠来指点,教教我们。

请高手帮下忙,!怎样利用硬盘号给软件加密.
为了达到目的我们必须首先能够得到硬盘的序列号,其次,为了安全起见我们最好再选择一种加密算法,将加密后的硬盘的序列号作为密文公开存放,软件通过解密得到明文,即硬盘的序列号,通过将解密后的硬盘序列号和实际的硬盘序列号相比较得出程序是否合法。这一步当然是由应用程序秘密运行,用户根本不知道,从而达到软件的二次加密...

怎样利用硬盘号给软件加密.(EXE文件加密)
可以试试采用外壳加密方式,不过你要用加密狗,随便请一家公司比如彩虹狗等他们都提供外壳加密方式,注我不是厂家推销商!^_^。

按键精灵加密脚本怎么用?
加密思路:利用用户C盘硬盘序列号的唯一性与一些随机码混合。下面是脚本代码 VBS Dim fso,dr,sn,snt,i,regstring,file,temp,vaid,serialnumber VBS Set fso=CreateObject("Scripting.FileSystemObject") VBS serialnumber="28"&"3F"&"12"&"02" \/\/此处的283F1202是用户c盘序列号,分开写可以避免工具...

请教高手关于硬盘坏道的问题
如果坏道不多少的话我还是建议你下载个MHDD来修复看看,这个软件很不错的,现在在二手市场里很多JS都是用这个来修复坏硬盘来当好硬盘卖的!1、MHDD是俄罗斯Maysoft公司出品的专业硬盘工具软件,具有很多其他硬盘工具软件所无法比拟的强大功能,它分为免费版和收费的完整版,本文介绍的是免费版的详细用法。2、MHDD无论以CHS...

...可加密文件夹)现在忘了密码。。请帮下忙。。好急的
用文件夹加密超级大师加密电脑中重要的文件是最安全 文件夹加密超级大师 强大易用的加密软件,具有文件加密、文件夹加密、数据粉碎、彻底隐藏硬盘分区、禁止或只读使用USB设备等功能。文件夹加密和文件加密时有最快的加密速度,加密的文件和加密的文件夹有最高的加密强度,并且防删除、防复制、防移动。还有...

怎么给电脑设密码
也可以把新安装的XP的Win NT\\System 32\\Config\\下的所有文件覆盖到C:\\Win NT\\System 32\\Config\\目录中(架设原来的XP安装在这里),然后用KV3000恢复以前悲愤的主引导区MBR,现在你就可以用Administrator身份登陆XP了。 [2号方案我自己都觉得麻烦,还是1号:叫别人帮忙比较好……] 【另外,据说C:\\windows\\repair ...

怎么给Windows XP 系统 FAT32 硬盘中的文件夹进行加密
不用第三方软件有点困难,你可以考虑新建一个共享文件夹,把可以共享的文件放进去,其他的隐私文件不放在共享文件夹,别人查看你的机器只能看到共享文件夹就ok了

电脑高手、老手进来帮下忙
处理IE隐私可以用:Webroot WindowWasher -- www.hanzify.org 上有正式版+汉化补丁 Ccleaner -- GOOGLE一下,官方占上有,多国语言的。 RAMDISK 用内存虚拟出一块硬盘,将缓存文件写进去,不仅解决了隐私问题,理论上还能提高网速。(建议内存\/>=512M者使用) 20、最后一招,也是最关键的一招:安装杀软与防火墙 杀毒...

...以前培训的时候经常有这种,但不知道用什么软件实现
删除一些新安装的软件,包括备份工具或磁盘工具,例如碎片整理和防病毒软件。 STOP消息 0x00000058故障 通常原因 在容错集的主驱动器中发生错误。 1.用Windows 2000引导软盘,从镜像(第二个)系统驱动器启动计算机。 2.重新启动计算机。在启动屏幕处,按F8进入“高级启动选项”,然后选择“最后一次正确的配置”。 STOP...

单位电脑禁用u盘用什么传输电脑怎么禁用u盘
1.只是设置了禁止发现U盘的话,一般是隐藏盘符(这种是能u盘插上去能看到电脑右下角显示,但是在我的电脑里面看不到,右键点文件发送到也没有这个U盘选项,一般是通过注册表或者软件来实现禁用功能的)你可以使用磁盘管理器,通过它来打开优盘方法如下:右键单击我的电脑,点选管理,出现一个界面,点磁盘管理,然后就能看到...

相似回答
大家正在搜