分享
 
 
 

保护自己的MIDlet程序之三:SNProtector

王朝other·作者佚名  2006-01-10
窄屏简体版  字體: |||超大  

作者:黑洞 文章来源:http://www.j2medev.com/Article/ShowArticle.asp?ArticleID=886

有了前面的基础,现在就开始实现SNProtector。

这回我们对SNProtector又有哪些要求和目标呢?

1。和前面的OnceProtector和TimeProtector一样要使用简单;

2。用户可以在程序里输入用户名和序列号并验证;

3。允许用户试用;

4。允许验证后继续运行程序。

好了,有了目标之后我们如何管理注册码呢?

放在资源里?放在程序里?这两种方法都不方便批量的分发。

哪里呢?我选择jad里面:)

分发的程序的jad里面有两个用户定义字段:

User: cakec

SN: 8180076728b161326ae2cc61b783b451

他们有什么用?看下去就明白了。

大家是不是又想到一个问题,如何可以像前面的两个Protector一样使用简便

只需要判断一下check,又能在用户输入注册码后再继续运行呢?

因为check判断和其它的startApp的初始工作在一个函数里面,难道有什么办法

让函数停止执行?然而如果主进程停止了执行,我又怎么显示输入注册码的界面,

响应用户的输入呢?思考10秒钟然后看我的方案:)

看看你跟我想的是不是一样:利用midlet的生命周期。

大家知道midlet每次pause之后再次切换的时候系统会调用startApp函数,

此时让check通过不就可以了。

ok,下面来看实现:

首先是注册码输入界面SNInputUI:

package vmlinux.app;

import javax.microedition.lcdui.*;

public class SNInputUI extends Form {

TextField tfUser_;

TextField tfSN_;

public SNInputUI()

{

super(StringManager.get("SNInputUI.Title"));

tfUser_=new TextField(StringManager.get("SNInputUI.User"),"",20,TextField.ANY);

tfSN_=new TextField(StringManager.get("SNInputUI.SN"),"",60,TextField.ANY);

this.append(tfUser_);

this.append(tfSN_);

}

public String getUser()

{

return tfUser_.getString();

}

public String getSN()

{

return tfSN_.getString();

}

}

这个没有难度,不说了。

然后是SNProtector:

我们需要使用新的UI来获取注册信息,所以构造函数是这样:

public SNProtector(MIDlet app)

{

super(app);

ui_=new SNInputUI();

cmdDone_=new Command(StringManager.get("SNProtector.Done"),Command.SCREEN,1);

cmdTry_=new Command(StringManager.get("SNProtector.Try"),Command.SCREEN,2);

ui_.addCommand(cmdDone_);

ui_.addCommand(cmdTry_);

}

由于我们已经设置了基类Protector为CommandListener,所以需要改造一下基类:

修改Protector的commandAction并增加doCommand函数

public void commandAction(Command c, Displayable d) {

if(c==cmdOK_)

app_.notifyDestroyed();

else

doCommand(c);

}

protected void doCommand(Command c)

{

}

然后在SNProtector重写doCommand:

protected void doCommand(Command c)

{

if(c==cmdDone_)

{

。。。

}

else if(c==cmdTry_)

{

。。。

}

}

当用户选择注册的时候,要做的工作就是把用户的输入保存起来。

如果用户选择了试用,就需要一个标志,说明用户要试用。

做完这些工作我们还需要提醒用户暂停程序,然后再恢复程序

以便达到我们重新调用startApp的目的。

所以完整的doCommand就是这样:

protected void doCommand(Command c)

{

if(c==cmdDone_)

{

SNInputUI input=((SNInputUI)ui_);

if(input.getUser().equals(app_.getAppProperty("User")))

{

try

{

RecordStore.deleteRecordStore(SNRMS);

}

catch(Exception ex)

{

//ignore

}

try

{

RecordStore rs=RecordStore.openRecordStore(SNRMS,true);

byte[] buf=input.getSN().getBytes();

rs.addRecord(buf,0,buf.length);

rs.closeRecordStore();

}

catch(Exception ex)

{

System.out.println(ex);

}

showAlert();

}

}

else if(c==cmdTry_)

{

tryit=true;

showAlert();

}

}

现在已经把用户输入的注册码保存了起来,在决定命运的check函数里就需要

把保存的信息读出来然后对比判断是否有效,这个就是check函数:

public boolean check()

{

if(tryit)

{

tryit=false;

return true;

}

boolean r=true;

try

{

RecordStore rs=RecordStore.openRecordStore(SNRMS,true);

RecordEnumeration e=rs.enumerateRecords(null,null,false);

if(e.hasNextElement())

{

r=checkCode(generate(app_.getAppProperty("User"),new String(e.nextRecord())));

}

else

{

r=false;

}

rs.closeRecordStore();

}

catch(Exception ex)

{

r=false;

}

if(!r)

{

showUI();

}

return r;

}

最后就是sn系统的核心checkCode和generate函数。

generate根据用户名和输入的注册码生成注册序列号

然后checkCode比较生成的注册序列号和验证码得出结论。

大家通过开头的注册码是不是已经知道了,我在这个例子中

简单的使用了md5加密来实现这个过程,下面就是实现:

boolean checkCode(byte[] x)

{

boolean r=true;

byte[] s=getCode();

if(x!=null && s!=null && x.length==s.length)

{

for(int i=0;i<x.length;++i)

if(x[i]!=s[i])

{

r=false;

break;

}

}

else

r=false;

return r;

}

byte[] getCode()

{

String sn=app_.getAppProperty("SN");

if(sn==null)

return null;

else

{

//deserialize sn from text

return sn.getBytes();

}

}

public byte[] generate(String user,String code)

{

String u=app_.getAppProperty("User");

if(u==null || !u.equals(user))

return null;

else

{

//compute inner-code from user and code

Md5 md5=new Md5(user+"\r\n"+code+"\r\nvmlinux snprotector");

try

{

md5.processString();

return md5.getStringDigest().getBytes();

}

catch(Exception ex)

{

System.out.println(ex);

return null;

}

}

}

怎么样,这就是我的SNProtector的工作过程。

使用方法:在startApp开始加入if(!new SNProtector(this).check())return;

最后你除了要把开头的两条内容加入jad文件还需要告诉用户一个密码:123456

这个就是cakec的注册密码。

这个SNProtector距离实际应用还有相当距离,因为加密方法太简单,随便生成密码

代入公式把生成的md5码放到SN里面即可,只能象征性的意思一下。如何有更好的加密算法?

这个话题就太大了:)

有意见或建议请联系vmlinuxx@gmail.com,共同学习,共同提高:)

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有