1、认证和授权

概述

认证是用来证明用户身份合法性的过程,授权是用来证明用户可以合法地做哪些事的过程,这两个过程一般是在服务器端执行的,但也有的APP出于性能提升或用户体验等原因,将其做在客户端完成,由此导致客户端绕过等问题。

安全准则

  1. 在客户端做认证和授权是很难保证安全的,所以应该把认证和授权做在服务器端。如果确实有特殊的需求,可以和安全工程师进行沟通做单一case分析。
  2. 尽可能避免在设备上存储用户名和密码,可以使用登录认证后获得的token进行鉴权(同时注意控制token的有效期)。

详细描述

Item B的典型应用场景是实现自动登录,用户登录认证后在本地存储用户的认证token,用户退出程序时认证token不会被删除,再次打开程序时可直接携带认证token获取数据,同时为了保证了足够的安全性,可以根据当前终端硬件信息产生独立密钥,然后对token进行加密。具体设计参考附录8。

备注

在本地存储对称加密后的用户口令密文,在登录时还原出明文也是实现自动登录的一种可选方案,但其安全性偏低,故在当今已并非一种主流的做法。

     

2、加密解密

概述

开发人员在移动应用中通常会对敏感数据进行加密处理,但是使用不当有可能让其保护强度削弱,甚至大打折扣,因此,正确的选择加解密算法显得非常重要。

安全准则

  1. 在不需要还原用户明文密码的场景使用哈希算法,在需要还原用户明文密码的场景下使用对称加密算法,并且始终优先选择使用哈希算法。
  2. 使用目前主流的安全加密算法,比如哈希算法可以使用sha256,对称加密算法可以使用AES128/256,不使用过时的不安全算法,比如RC4、RC5、MD5和SHA1。
  3. 不使用自定义的加密算法。
  4. 密文和密钥不要放在同一文件或同一目录内,应分开存放。
  5. 密钥不可硬编码在代码里面。

详细描述

使用AES128加密算法时,密钥应同时满足长度(128bit)和复杂度的要求,建议使用安全的随机数发生器产生安全的密钥,Sha256哈希算法和AES128对称加密算法的使用方法请参考附录1。

备注

注意:在某些不牵涉敏感数据的场景下,不安全的哈希算法仍然是可用的,比如用于校验文件或数据的完整性。

     

3、安全配置和部署

概述

安全开发可以大大降低移动应用的安全风险,同样地,安全的配置和部署可以让风险降到最低。

安全准则

  1. 确保使用的第三方组件是从官方下载的,并且是最新版本的。
  2. 为应用程序申请最小的Permissions,如果用不上就不要申请。
  3. 应用和补丁在发布前建议进行病毒和恶意代码检测。
  4. 为敏感数据输入界面提供防截屏措施,对抗木马。

详细描述

在Activity的onCreate()方法的初始化部分加入以下代码可用于防截屏:

getWindow().addFlags(WindowManager.LayoutParams. FLAG_SECURE);

备注

非官方的库可能被植入恶意代码,而使用最新版本的库(非beta版)可以降低漏洞存在的可能性。

     

4、应用加固

概述

通常一个应用发布后可能会面临以下风险:

A.  应用被别人解包植入广告或恶意代码再重打包发布。

B.  应用被暴力破解。

C.  应用的核心关键代码逻辑被逆向。

因此,有必要在技术层面采取一定的缓解措施。

安全准则

  1. 对Java代码进行混淆,对抗反编译。
  2. 对Native代码进行加壳,对抗反汇编。
  3. 应用程序加入动态反调试方法。
  4. 应用程序加入防二次打包的方法。

详细描述

  1. 可以使用proguard对Java源码进行混淆。
  2. 可以使用UPX进行加壳保护,请参考《Android SO加壳指南v1.0》。
  1. 预先在AndroidManifest.xml文件插入android:debuggable=”false”,在程序中判断该标志位是否被篡改,此外,android SDK也提供了相关方法来检测调试器是否已连接,可在程序中随机插入检测,关键代码如下(详情参考附录10):
  2. 应用程序被篡改并重打包时必定要重新签名,签名值和原开发者的必定不一样(不考虑证书丢失的情况),另外,重新编译程序classes.dex文件肯定会变,因此可在程序运行时对比签名或CRC值的方法对抗重打包(参考附录11)。

备注

以上方案参考《Android软件安全与逆向分析》一书,但只能提供比较基本的保护措施,如果要进一步提高攻击者的攻击门槛,建议使用第三方的定制方案。

     

5、MISC(其它)

概述

本项作为其它移动客户端项的进一步补充。

安全准则

  1. 关键性业务逻辑代码应放在native代码实现,除此以外,尽量使用android SDK做开发,减少对native代码的依赖(native代码一般采用C/C++编写,容易出现缓冲区溢出等漏洞)。
  2. 尽量少用动态加载的方式执行代码(比如使用DexClassLoader),如果需要从外部存储动态加载可执行文件或类文件(比如使用DexClassLoader),应经过严格的文件完整性验证。

详细描述

文件完整性校验方案(参考附录9):

  1. 对待动态加载的可执行文件或类文件进行哈希计算,并与存储在服务器端的正确的哈希值进行对比,如果一致则表示文件未被篡改过,否则拒绝执行加载。

备注

存放在外部存储的文件是可公共访问的,可能会被其它恶意进程篡改,动态加载这些文件就有可能导致恶意代码执行。

     

6、服务器端的安全

概述

大部分移动应用并非一个独立的单机程序,需要在服务器的支撑下完成一系列的功能,而服务器一般是以web API、web service等方式为移动客户端提供服务,因此,也同样存在web应用的安全问题,而这部分问题牵涉面广而复杂,无法在单独的item内进行描述,可参考《web安全开发指南》

安全准则

请参考《web安全开发指南》

详细描述

 

备注

10、Android动态反调试方案:

10.1、检测AndroidManifest.xml的调试标志位是否被篡改:

if((getApplicationInfo().flags &= ApplicationInfo.FLAG_DEBUGGABLE) != 0){

System.exit(1);//使程序强制退出

}

注意:使用此方法时必须预先在AndroidManifest.xml设置android:debuggable=”false”,攻击者要尝试调试应用时很有可能去修改该参数,因而此手法可用于做动态反调试检测。

10.2、检测应用程序是否连接调试器:

if(android.os.Debug.isDebuggerConnected()){

System.exit(1);

}

11、防止二次打包方案:

11.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);//不一致则强制程序退出

}

11.2、CRC校验保护

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值置不能够预置在代码中,可以考虑置放在资源文件中。

移动应用安全开发指南(Android)--完结篇(http://www.bubuko.com/infodetail-577312.html)的更多相关文章

  1. Java工程师学习指南(完结篇)

    Java工程师学习指南 完结篇 先声明一点,文章里面不会详细到每一步怎么操作,只会提供大致的思路和方向,给大家以启发,如果真的要一步一步指导操作的话,那至少需要一本书的厚度啦. 因为笔者还只是一名在校 ...

  2. ScreenToGif 使用指南(完结篇)

    ScreenToGif 是个强大的 Gif 录制/剪辑工具.其使用指南译文如下: 第一部分:录制 第二部分:编辑器 第三部分:主页.播放 第四部分:编辑.图像.过渡.统计 第五部分(完结篇)如下: 2 ...

  3. OpenCV On Android环境配置最新&最全指南(Android Studio篇)

    本文是从本人简书上搬运而来,属本人原创,如有转载,请注明出处:http://www.jianshu.com/p/6e16c0429044 简介 本文是<OpenCV On Android环境配置 ...

  4. JNI/NDK开发指南(开山篇)

    转载请注明出处:http://blog.csdn.net/xyang81/article/details/41759643 相信很多做过Java或Android开发的朋友经常会接触到JNI方面的技术, ...

  5. 移动应用安全开发指南(Android)--Android组件和IPC

    概述 移动应用开发中,往往有跨进程通信的需求,方便地实现程序间的数据共享.Android提供了多种IPC通信的方式,给开发人员带来了便利,但如果选择或使用不当,就有可能发生各种各样的风险. 安全准则 ...

  6. Flutter 快捷开发 Mac Android Studio 篇

    老孟导读:此快捷方式适用于Mac下的 Android Studio .Windows 下的快捷方式请参考这篇文章:https://juejin.im/post/5efe71365188252e7d7f ...

  7. [地图SkyLine二次开发]框架(5)完结篇

    上节讲到,将菜单悬浮到地图上面,而且任何操作都不会让地图把菜单盖住. 这节带大家,具体开发一个简单的功能,来了进一步了解,这个框架. 1.想菜单中添加按钮 -上节定义的mainLayout.js文件里 ...

  8. 移动应用安全开发指南(Android)--数据验证

    概述 移动应用往往通过数据的发送.接收和处理来完成一系列功能,通常情况下,处理的数据绝大部分都来源于外部(比如网络.内部或外部存储和用户输入等),对这些数据处理不当会导致各种各样的漏洞和风险,比代码执 ...

  9. 移动应用安全开发指南(Android)--完结篇

    如果IE显示格式不正常,请使用chrome浏览器 1.认证和授权 概述 认证是用来证明用户身份合法性的过程,授权是用来证明用户可以合法地做哪些事的过程,这两个过程一般是在服务器端执行的,但也有的APP ...

随机推荐

  1. 人脸识别经典算法二:LBP方法

    与第一篇博文特征脸方法不同,LBP(Local Binary Patterns,局部二值模式)是提取局部特征作为判别依据的.LBP方法显著的优点是对光照不敏感,但是依然没有解决姿态和表情的问题.不过相 ...

  2. hdu 4648 - Magic Pen 6(“水”题)

    摘自题解: 题意转化一下就是: 给出一列数a[1]...a[n],求长度最长的一段连续的数,使得这些数的和能被M整除. 分析: 设这列数前i项和为s[i], 则一段连续的数的和 a[i]+a[i+1] ...

  3. 安装GO语言环境之安装Visual Studio Code插件

    在安装Visual Studio Code插件的时候,由于谷歌的限制,在下载下列插件的时候会报错: go get -u -v github.com/nsf/gocode go get -u -v gi ...

  4. PostgreSQL学习记录-- 2016-03-11

    1.日期字段 “年月日”  使用 date “年月日 时分秒” 使用 timestamp without time zone 2.布尔字段 使用 boolean 3.字符字段 使用 character ...

  5. Kali Linux Web 渗透测试视频教程— 第八课 nessus

    Kali Linux Web 渗透测试视频教程— 第八课 nessus 文/玄魂 视频课程地址:http://edu.51cto.com/course/course_id-1887.html 目录 n ...

  6. 写给自己看的Linux运维基础(三) - Mono

    如果使用ubuntu,可使用apg-get安装完mono,xsp,mod_mono,我的yum源并没有找到mono可安装,网上也没找到CentOS的源,最后选择下载编译安装. Stackoverflo ...

  7. [BTS] Action demo In BizTalk WCF-SAP Adapter

    I use following xml config in BizTalk 2010 WCF-SAP adapter. <BtsActionMapping xmlns:xsi="htt ...

  8. SpringMVC实现一个controller写多个方法

    MultiActionController与ParameterMethodNameResolver在一个Controller类中定义多个方法,并根据使用者的请求来执行当中的某个方法,相当于Struts ...

  9. 工作圈redis 使用

    redis作为内存数据库,更多的是作为内存cache来使用. 再所负责的工作圈中的使用,主要是分两方面: 1.数据对象: 主题的内容存储 主题回复内容的存储 用户信息存储 圈子信息存储 2.各数据对象 ...

  10. LDR 和 ADR 彻底详解

    0.什么是位指令? 答:伪指令(Pseudo instruction)是用于告诉汇编程序如何进行汇编的指令.它既不控制机器的操作也不被汇编成机器代码, 只能为汇编程序所识别并指导汇编如何进行. 1.L ...