用VB定制口令登录控件

王朝厨房·作者佚名  2007-01-04
窄屏简体版  字體: |||超大  

福州市鳌峰路118号福州人造板厂 张和据

大家知道,为防止非授权人随意运行软件,可以在该软件中设置密码而达到保护软件不被随意运行的目的。如果直接在软件中设置密码,至少存在两点不足:1、密码容易被PCTOOLS之类的工具软件窥视到;2、给普通用户修改密码带来困难。为此,笔者用VB5.0制作口令登录ACTIVEX控件PASSWORD.OCX,该控件将口令加密后以文件的形式保存,工具软件无法看到密码,而用户修改口令却很方便。笔者认为虽然自编的口令登录控件在加密算法方面比较简单,但因其不象专业加密软件那样广泛应用,不至于引起众多的解密者挖空心思对其解密,反而更安全。当你用兼容ACTIVEX控件的语言编写应用软件时,只需将PASSWORD.OCX控件加入你的软件之中,就可使应用软件具有口令登录的功能。

该控件将口令加密后以文件的形式储存在WINDOWS目录下。加密方法为:产生随机数与每个口令字符的ASCII码异或,再乘以该随机数后储存.并将随机数和口令长度加密后保存。该控件的具体制作过程如下:

1、设计控件外观。运行VB,选择新建ACTIVEX控件,制作如图1所示的登录窗体,把工程名称改为PASSWORD。

2、设置控件属性、方法。在VB菜单的外接程序里找到ACTIVEX控件向导,按照向导提示逐步完成。具体过程为:在选定界面成员窗体步骤中选中TIMER事件,在创建自定义界面成员步骤中定义OPENPASWD方法及GETLOGONINFO属性(获取登录成功与否的信息)、GETCOUNTFT属性(获取输入口令次数的信息)和PRESS事件。在设置映射步骤中将TIMER事件映射到控件TIMER1,成员TIMER之中。在设置属性步骤中,将GETCOUNTFT及GETLOGONINFO属性数据类型设置为BOOLEAN,缺省值为0。至此,ACTIVEX控件向导设置完成。

3、在控件中添加模块MODULE1,并在代码中加入如下申明:

DECLARE FUNCTION GETWINDOWSDIRECTORY LIB "KERNEL32" ALIAS "GETWINDOWSDIRECTORYA" _

(BYVAL LPBUFFER AS STRING, BYVAL NSIZE AS LONG) AS LONG 注释:获取WINDOWS目录

4、编写控件代码,完成口令登录、口令修改功能,其代码如程序1所示。

5、编译PASSWORD.OCX控件。

口令登录控件编译完成之后,可以把它加入工具箱中,供应用程序使用。当我们把应用软件提供给用户时,可以通过安装程序把初始口令装在WINDOWS目录下,安装程序的创建可参考有关书籍。

为了演示该控件,先将初始口令为123的口令文件TST.DAT拷贝到WINDOWS目录下,在VB中建立标准的EXE工程,将PASSWORD.OCX控件添加到工具箱中,制作如图2所示的窗体,编写如程序2所示代码,编译后运行,输入123便进入登录成功的FORM2窗体中,如果输入三次口令均不对则程序终止。在实际应用中FORM2窗体就应该是我们应用软件在口令登录成功后下一步需要作的内容。

本控件程序在WINDOWS ME、WINDOWS98,VB5.0环境下,调试运行通过。

TST.DAT的内容为:"DON注释:T MODIFY THESE DATA",191165,438555,126258860,126292595,126281350,3733101,3699366,3665631,3631896,3598161,3564426,3530691,3496956,

程序1 (口令控件代码)

DIM PSW AS STRING

DIM PASOK AS BOOLEAN

DIM PASNEW AS STRING

DIM PASFIRST AS STRING

DIM PASNUM AS BOOLEAN

DIM LENG AS LONG

DIM PASOLD AS STRING

DIM FLAG AS STRING

DIM FIRST AS INTEGER

DIM LP AS LONG

DIM LPP AS LONG

DIM GETINFO AS BOOLEAN

DIM GETCOUNT AS BOOLEAN

DIM WINDIR AS STRING

DIM WINDIRLEN AS LONG

DIM WINDIRS AS STRING

PUBLIC EVENT PRESS()

注释:EVENT DECLARATIONS:

EVENT TIMER() 注释:MAPPINGINFO=TIMER1,TIMER1,-1,TIMER

PRIVATE SUB COMMAND1_CLICK() 注释:如果口令正确就登录

STATIC LOOPNUM AS INTEGER

LOOPNUM = LOOPNUM + 1

IF LOOPNUM > 2 THEN GETCOUNT = FALSE 注释:判断输入口令次数是否超过3次

PSW = "NO"

PASOLD = TEXT1.TEXT

CALL OPENPASWD

IF LENG <> LEN(TEXT1.TEXT) THEN PSW = "NO" 注释:判断输入口令是否与原口令长度相等

IF STRCOMP(PSW, "NO") = 0 THEN

LABEL2.CAPTION = "口令错,请重新输入!"

TEXT1.TEXT = ""

TEXT1.SETFOCUS

ELSE:

GETINFO = TRUE 注释:口令正确

END IF

RAISEEVENT PRESS

END SUB

PUBLIC SUB OPENPASWD() 注释:打开口令文件

T = 0

ON ERROR RESUME NEXT 注释: 将错误处理的方式改为"继续下一行"。

OPEN WINDIRS & "\TST.DAT" FOR INPUT AS #1 注释:读取口令密文

IF ERR.NUMBER <> 0 THEN

P = MSGBOX("口令已被破坏无法运行", 16, "退出应用软件")

ERR.CLEAR

GETCOUNT = FALSE

END IF

INPUT #1, INFO, NUM, LENG

NUM = NUM / 17

LENG = (LENG / NUM) / 13 注释:解密口令长度及口令

DO WHILE T <= LENG - 1

T = T + 1

INPUT #1, CHR1

LP = CHR1 / NUM

LPP = LP XOR NUM

PASS = CHR(LPP)

IF STRCOMP(PASS, RIGHT(LEFT(PASOLD, T), 1)) <> 0 THEN

PSW = "NO"

ELSE: PSW = "YES"

END IF

LOOP

CLOSE

END SUB

PRIVATE SUB COMMAND2_CLICK() 注释:如果输入正确的原口令就更改口令

INFO = "DON注释:T MODIFY THESE DATA"

IF PSW = "YES" THEN

PASNUM = TRUE

PASNEW = TEXT2.TEXT

IF STRCOMP(PASFIRST, PASNEW) = 0 THEN PASOK = TRUE

IF PASOK = TRUE THEN

T = 0

OPEN WINDIRS & "\TST.DAT" FOR OUTPUT AS #1 注释:将口令文件创建在WINDOWS目录下

SAV = PASNEW

RANDOMIZE

NUM = INT(10000 * RND(20)) + 1 + INT(RND(60) * 10000) 注释:随机数

KK = LEN(SAV)

WRITE #1, INFO, NUM * 17, KK * NUM * 13, 注释:将随机数及变换后的口令长度写入文件

DO WHILE T <= KK - 1 注释:加密口令

T = T + 1

CHRQ = LEFT(SAV, T)

CHR1 = RIGHT(CHRQ, 1)

LP = ASC(CHR1) XOR NUM

LPP = LP * NUM

WRITE #1, LPP,

LOOP

IF KK < 10 THEN 注释:如果口令长度少于10个字符,继续写入字符,防止解密者猜测口令长度

LL = 10 - KK

DO WHILE LL >= 0

WRITE #1, NUM * KK * (LL + 100) + 123456,

LL = LL - 1

LOOP

END IF

CLOSE

LABEL2.FORECOLOR = QBCOLOR(3)

LABEL2.CAPTION = "口令更改成功!"

TIMER1.ENABLED = TRUE

END IF

IF PASNUM = TRUE AND PASOK = FALSE THEN 注释:允许有三次确认新口令的机会

LABEL2.FORECOLOR = QBCOLOR(13)

LABEL2.CAPTION = "请再输入一次新口令!"

FIRST = FIRST + 1

IF FIRST = 1 THEN PASFIRST = PASNEW

IF FIRST > 3 THEN GETCOUNT = FALSE

TEXT2.TEXT = ""

TEXT2.SETFOCUS

END IF

ELSE:

STATIC LOOPNUM AS INTEGER 注释:有三次机会输入原口令

LOOPNUM = LOOPNUM + 1

IF LOOPNUM > 2 THEN GETCOUNT = FALSE

PASOLD = TEXT2.TEXT

CALL OPENPASWD

IF LENG <> LEN(PASOLD) THEN PSW = "NO"

IF STRCOMP(PSW, "NO") = 0 THEN

LABEL2.FORECOLOR = QBCOLOR(12)

LABEL2.CAPTION = "口令错,请重新输入!"

TEXT2.TEXT = ""

TEXT2.SETFOCUS

END IF

IF STRCOMP(PSW, "YES") = 0 THEN

LABEL2.FORECOLOR = QBCOLOR(4)

LABEL2.CAPTION = "请输入新口令!"

TEXT2.TEXT = ""

TEXT2.SETFOCUS

PASNUM = TRUE

END IF

END IF

RAISEEVENT PRESS

END SUB

PRIVATE SUB OPTION1_CLICK() 注释:更改口令

TEXT2.SETFOCUS

LABEL2.CAPTION = "请输入原口令!"

RAISEEVENT PRESS

END SUB

PRIVATE SUB TIMER1_TIMER() 注释:延时2秒关闭登录窗口

GETCOUNT = FALSE

RAISEEVENT TIMER

END SUB

PUBLIC PROPERTY GET GETLOGONINFO() AS BOOLEAN

GETLOGONINFO = GETINFO

END PROPERTY

PRIVATE SUB USERCONTROL_INITIALIZE()

WINDIR = STRING(255, 0)

WINDIRLEN = GETWINDOWSDIRECTORY(WINDIR, 255)

WINDIRS = LEFT(WINDIR, WINDIRLEN)

PSW = "NO"

TIMER1.INTERVAL = 2000

LOOPNUM = 0

TIMER1.ENABLED = FALSE

PASNUM = FALSE

PASOK = FALSE

FIRST = 0

GETINFO = FALSE

GETCOUNT = TRUE

END SUB

PUBLIC PROPERTY GET GETCOUNTFT() AS BOOLEAN

GETCOUNTFT = GETCOUNT

END PROPERTY

程序2:(演示程序)

PRIVATE SUB USERCONTROL11_PRESS()

IF USERCONTROL11.GETLOGONINFO = TRUE THEN

UNLOAD FORM1

FORM2.SHOW

END IF

IF USERCONTROL11.GETCOUNTFT = FALSE THEN

UNLOAD FORM1

END IF

END SUB

PRIVATE SUB USERCONTROL11_TIMER()

IF USERCONTROL11.GETCOUNTFT = FALSE THEN

UNLOAD FORM1

END IF

END SUB

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
 
 
© 2005- 王朝網路 版權所有 導航