探索黑客技术攻防,实战研究与安全创新

导航菜单

打造实用的Android程序锁

手机程序锁是安卓上一款加密应用程序的安全类工具,当你打开某个应用程序的时候,如果已经对其加锁,则会弹出密码框或者图形锁,输入正确后才可以进入,其可以对所有的APK程序进行加密,包括打开图片处理软件,音乐软件,短信,微信等等.那么现有的程序锁实用吗?答案是确定的,经本人测试不太实用。存在以下几个问题:

1)不够方便的解锁处理;

2)密码存储的加密保护不够好;

3)整个程序锁进程可以被结束掉,保护如同虚设。所以,让我们来打造一个实用的程序锁。

原理分析

程序锁的应用是一个服务定时监视顶层Activity,如果Activity对应的包名是之前上锁的应用程序的,则弹出一个页面要求输入解锁密码,这里我们改成图形解锁,通过判断解锁密码是否与之前设定的相符,来决定是否正常使用这些软件。

而密码存储可以进行加密处理,所以不做过多分析,进程保护的方法我在14年一期里介绍到过,所以这里也不做讲解了,代码嵌套进去即可。而为了更加方便用户的使用,采用九宫格方式解锁,其原理将会在下面的编程分析里详细介绍。

编程分析

1.九宫格的设计与绘制

图案解锁原理:先绘制九个点,其实就是找个九个位置,给九个点绘制图案;考虑图案正常下的状态,用户点击的时候的状态;要考虑连线错误时候的状态,图案的限制;在设置密码的时候,画图连线保存成密码。


privatevoiddrawLine(Pointstart,Pointend,Canvascanvas,Paintpaint){
doubled=MathUtil.distance(start.x,start.y,end.x,end.y);
floatrx=(float)((end.x-start.x)*dotRadius/4/d);
floatry=(float)((end.y-start.y)*dotRadius/4/d);
canvas.drawLine(start.x+rx,start.y+ry,end.x-rx,end.y-ry,paint);
}
privatevoiddrawArrow(Canvascanvas,Paintpaint,Pointstart,Pointend,floatarrowHeight,
intangle){
doubled=MathUtil.distance(start.x,start.y,end.x,end.y);
floatsin_B=(float)((end.x-start.x)/d);
floatcos_B=(float)((end.y-start.y)/d);
floattan_A=(float)Math.tan(Math.toRadians(angle));
floath=(float)(d-arrowHeight-dotRadius*1.1);
floatl=arrowHeight*tan_A;
floata=l*sin_B;
floatb=l*cos_B;
floatx0=h*sin_B;
floaty0=h*cos_B;
floatx1=start.x+(h+arrowHeight)*sin_B;
floaty1=start.y+(h+arrowHeight)*cos_B;
floatx2=start.x+x0-b;
floaty2=start.y+y0+a;
floatx3=start.x+x0+b;
floaty3=start.y+y0-a;
Pathpath=newPath();
path.moveTo(x1,y1);
path.lineTo(x2,y2);
path.lineTo(x3,y3);
path.close();
canvas.drawPath(path,paint);
}
privatevoidinitCache(){
width=this.getWidth();
height=this.getHeight();
floatx=0;
floaty=0;
if(width>height){
x=(width-height)/2;
width=height;
}else{
y=(height-width)/2;
height=width;
}
intleftPadding=15;
floatdotPadding=width/3-leftPadding;
floatmiddleX=width/2;
floatmiddleY=height/2;
mPoints[0][0]=newPoint(x+middleX-dotPadding,y+middleY-dotPadding,1);
mPoints[0][1]=newPoint(x+middleX,y+middleY-dotPadding,2);
mPoints[0][2]=newPoint(x+middleX+dotPadding,y+middleY-dotPadding,3);
mPoints[1][0]=newPoint(x+middleX-dotPadding,y+middleY,4);
mPoints[1][1]=newPoint(x+middleX,y+middleY,5);
mPoints[1][2]=newPoint(x+middleX+dotPadding,y+middleY,6);
mPoints[2][0]=newPoint(x+middleX-dotPadding,y+middleY+dotPadding,7);
mPoints[2][1]=newPoint(x+middleX,y+middleY+dotPadding,8);
mPoints[2][2]=newPoint(x+middleX+dotPadding,y+middleY+dotPadding,9);
Log.d(jerome,canvaswidth:+width);
dotRadius=width/10;
isCache=true;
initPaints();
}


2.程序锁后台服务实现

启动定时器,新建任务,先获取当前顶层的应用程序包名,读取数据库,判断是否加锁的包名,是的话则要跳转到我们写好的解锁画面。如果是第一次打开,则跳出设置解锁的图案,这样每个应用程序解锁图案都不一样,可以提高安全性。如果不是枷锁的包名,则不做任何操作,允许进入使用。核心代码如下:


privatevoidstartTimer(){
if(timer==null){
newTimer().schedule(newTimerTask(){
@Override
publicvoidrun(){
Log.i(patternlock,timerisstarted);
ComponentNamecn=am.getRunningTasks(1).get(0).topActivity;
StringpackageName=cn.getPackageName();
StringclassName=cn.getClassName();
Log.i(patternlock,packageName)
if(!lastpack.equals(packageName)!packageName.equals(com.example.patternlock)){
Check.getIntence().saveIsFinished(context,lastpack,false);
Check.getIntence().saveOpened(context,lastpack+locked,false);
}
if(dbs.query(packageName)){
if
(Check.getIntence().getIsFinished(context,packageName)||Check.getIntence().getLockOpened(con
text,packageName+locked)){
//Toast.makeText(context,foundbutlocked,3000).show();
Log.i(patternlock,checked);
return;
}else{
//Toast.makeText(context,foundandshow,3000).show();
Check.getIntence().saveOpened(context,packageName+locked,true);
Intentintent=newIntent();
intent.setClassName(com.example.patternlock,
com.example.patternlock.WelActivity);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
Bundlebundle=newBundle();
bundle.putString(packName,packageName);
intent.putExtras(bundle);
startActivity(intent);
}
lastpack=packageName;
}else{
//Toast.makeText(context,didnotfind,3000).show();
return;
}
//Looper.loop();
}
},1000,1000);}}


编译以上代码,运行程序打开界面,设置枷锁应用如图1所示。

第二次打开加锁应用,会弹出设置好的密码解锁,如图2所示。

A25.png

图2

经过测试,本程序可以实现程序锁的功能,九宫格解锁,进程保护代码我在2014年一期讲过,直接嵌入进去就可以了,可以保证不会在后台被结束掉,但是密码没有加密存储,可定义一个算法,用一些常用的算法接口,这样一个实用的程序锁就完成了。