概述android
|
认证是用来证实用户身份合法性的过程,受权是用来证实用户能够合法地作哪些事的过程,这两个过程通常是在服务器端执行的,但也有的APP出于性能提高或用户体验等缘由,将其作在客户端完成,由此致使客户端绕过等问题。web |
|
安全准则算法
|
|
|
详细描述安全
|
Item B的典型应用场景是实现自动登陆,用户登陆认证后在本地存储用户的认证token,用户退出程序时认证token不会被删除,再次打开程序时可直接携带认证token获取数据,同时为了保证了足够的安全性,能够根据当前终端硬件信息产生独立密钥,而后对token进行加密。具体设计参考附录8。服务器 |
|
备注web安全
|
在本地存储对称加密后的用户口令密文,在登陆时还原出明文也是实现自动登陆的一种可选方案,但其安全性偏低,故在当今已并不是一种主流的作法。性能 |
|
概述this
|
开发人员在移动应用中一般会对敏感数据进行加密处理,可是使用不当有可能让其保护强度削弱,甚至大打折扣,所以,正确的选择加解密算法显得很是重要。编码 |
|
安全准则加密
|
|
|
详细描述
|
使用AES128加密算法时,密钥应同时知足长度(128bit)和复杂度的要求,建议使用安全的随机数发生器产生安全的密钥,Sha256哈希算法和AES128对称加密算法的使用方法请参考附录1。 |
|
备注
|
注意:在某些不牵涉敏感数据的场景下,不安全的哈希算法仍然是可用的,好比用于校验文件或数据的完整性。 |
|
概述
|
安全开发能够大大下降移动应用的安全风险,一样地,安全的配置和部署可让风险降到最低。 |
|
安全准则
|
|
|
详细描述
|
在Activity的onCreate()方法的初始化部分加入如下代码可用于防截屏: getWindow().addFlags(WindowManager.LayoutParams. FLAG_SECURE); |
|
备注
|
非官方的库可能被植入恶意代码,而使用最新版本的库(非beta版)能够下降漏洞存在的可能性。 |
|
概述
|
一般一个应用发布后可能会面临如下风险: A. 应用被别人解包植入广告或恶意代码再重打包发布。 B. 应用被暴力破解。 C. 应用的核心关键代码逻辑被逆向。 所以,有必要在技术层面采起必定的缓解措施。 |
|
安全准则
|
|
|
详细描述
|
|
|
备注
|
以上方案参考《Android软件安全与逆向分析》一书,但只能提供比较基本的保护措施,若是要进一步提升攻击者的攻击门槛,建议使用第三方的定制方案。 |
|
概述
|
本项做为其它移动客户端项的进一步补充。 |
|
安全准则
|
|
|
详细描述
|
文件完整性校验方案(参考附录9):
|
|
备注
|
存放在外部存储的文件是可公共访问的,可能会被其它恶意进程篡改,动态加载这些文件就有可能致使恶意代码执行。 |
|
概述
|
大部分移动应用并不是一个独立的单机程序,须要在服务器的支撑下完成一系列的功能,而服务器通常是以web API、web service等方式为移动客户端提供服务,所以,也一样存在web应用的安全问题,而这部分问题牵涉面广而复杂,没法在单独的item内进行描述,可参考《web安全开发指南》 |
|
安全准则
|
请参考《web安全开发指南》 |
|
详细描述
|
||
备注
|
|
if((getApplicationInfo().flags &= ApplicationInfo.FLAG_DEBUGGABLE) != 0){
System.exit(1);//使程序强制退出
}
注意:使用此方法时必须预先在AndroidManifest.xml设置android:debuggable=”false”,攻击者要尝试调试应用时颇有可能去修改该参数,于是此手法可用于作动态反调试检测。
if(android.os.Debug.isDebuggerConnected()){
System.exit(1);
}
public class getSign {
public static int getSignature(PackageManager pm , String packageName){
PackageInfo pi = null;
int sig = 0;
Signature[]s = null;
try{
pi = pm.getPackageInfo(packageName, PackageManager.GET_SIGNATURES);
s = pi.signatures;
sig = s[0].hashCode();//s[0]是签名证书的公钥,此处获取hashcode方便对比
}catch(Exception e){
handleException();
}
return sig;
}
}
主程序代码参考:
pm = this.getPackageManager();
int s = getSign.getSignature(pm, "com.hik.getsinature");
if(s != ORIGNAL_SGIN_HASHCODE){//对比当前和预埋签名的hashcode是否一致
System.exit(1);//不一致则强制程序退出
}
private boolean checkcrc(){
boolean checkResult = false;
long crc = Long.parseLong(getString(R.string.crc));//获取字符资源中预埋的crc值
ZipFile zf;
try{
String path = getApplicationContext().getPackageCodePath();//获取apk安装路径
zf = new ZipFile(path);//将apk封装成zip对象
ZipEntry ze = zf.getEntry("classes.dex");//获取apk中的classes.dex
long CurrentCRC = ze.getCrc();//计算当前应用classes.dex的crc值
if(CurrentCRC != crc){//crc值对比
checkResult = true;
}
}catch(IOException e){
handleError();
checkResult = false;
}
return checkResult;
}
注意:一旦修改源代码,从新编译后classes.dex的CRC值就会变掉,所以正确的CRC值置不可以预置在代码中,能够考虑置放在资源文件中。