【原创】总结Android应用安全

Android应用安全总结

额, 自己平时很少写文章,所以感觉自己平时学习到很多,但是都无法表达出来,也没办法讲给别人,所以还是多写写文章来总结下自己学习的东西。

对于Android安全个人感觉一般都是相对的,不同安全级别防不同级别的人。真正完全安全还是很难的,所谓道高一尺魔高一丈。

我这里整理了几点平时常用的安全操作,分享给大家。

本地数据安全

这个大家应该都有这个安全意识,对于干Android新手来说还是需要提一提的,新人往往没有这个安全意识,所以在保存在SP或者数据库里面的数据都是不经过加密,这样如果是一些密钥数据肯定是不安全的,而且很容易被别人拿到。

键值对存储安全

例如我们存储在SP里面手机号 , Token , 用户ID以及签名所需要的密钥,这些都是尽量通过加密以后存储密文。这里推荐对于Key-Value的存储可以使用腾讯开源库MMKV。我们可以通过如下调用加密保存数据以达到数据安全,该库还有很多其他方法有兴趣可以深入研究下。

val kv = MMKV.defaultMMKV(MMKV.SINGLE_PROCESS_MODE, "hello")
kv?.putString("hello", "hello")

数据库存储安全

我们肯定是使用加密的数据库来保证数据安全了,这里以Room框架来说明,我们需要添加sqlcilpher来实现数据库加密

plugins {
    id("com.android.application")
    id("kotlin-android")
    id("kotlin-kapt")
}
.....
dependencies {
	// 数据
	val room_version = "2.2.6"
	implementation("androidx.room:room-runtime:$room_version")
	kapt("androidx.room:room-compiler:$room_version")
	implementation("androidx.room:room-ktx:$room_version")

	implementation("net.zetetic:android-database-sqlcipher:4.4.2")
	implementation("androidx.sqlite:sqlite-ktx:2.1.0")
}

然后在初始化数据库时候,添加这个加密库的Factory即可

private fun buildDatabase(context: Context): PolarisDb {
	return Room.databaseBuilder(context, PolarisDb::class.java, DB_NAME)
                .openHelperFactory(SupportFactory(SQLiteDatabase.getBytes(password.toCharArray())))
                .build()
}

清单文件配置

清单文件里的有个属性需要配置,不然一些安全软件扫描都会提示你错误

<application
    android:allowBackup="false" // 这里需要配置false
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:roundIcon="@mipmap/ic_launcher_round"
    android:supportsRtl="true"
    android:theme="@style/Theme.LpcApps">

android:allowBackup这个属性就是防止被备份数据,属性具体说明可以读读Android之allowBackup属性讲的很详细了

网络报文安全

网络安全最基本的就是使用https协议来保证数据安全,https协议对网络报文进行加密传输,相对http安全很多。

报文加密

那使用Https是不是就安全了,当然不是!还有个工具叫抓包工具,常用的有FiddlerCharles,高级点的用Wireshark。我们的报文其实还是明文裸奔。所以还需要对报文进行加密和签名。通常我们加密报文后传出的参数就两个一个data加密的报文还有一个sign报文签名。下面是简单实现

val json = """
{"key1":"value1", "key1":"value2"}
"""
val data = AES(json) // 还可以选用3DES等
val sign = MD5(data) // 还可以选用SHA等
val content = """
{"data":$data, "sign":$sign)
"""
val JSON = MediaType.get("application/json; charset=utf-8");
RequestBody body = RequestBody.create(JSON, content);
Request request = new Request.Builder()
      .url(url)
      .post(body)
      .build();
try (Response response = client.newCall(request).execute()) {
   val resp = response.body().string();
}

无代理配置

相信目前80%~90%的应用都是基于或者所使用的库基于OkHttp进行网络请求。不像早些年,还是自己去封装HttpURLConnect去收发报文。为了防止抓包我们还可以通过OkHttp来配置Proxy.NO_PROXY,代码如下:

OkHttpClient.Builder()
     .connectTimeout(DEFAULT_TIMEOUT, TimeUnit.MILLISECONDS)
     .writeTimeout(DEFAULT_TIMEOUT, TimeUnit.MILLISECONDS)
     .readTimeout(DEFAULT_TIMEOUT, TimeUnit.MILLISECONDS)
     .proxy(Proxy.NO_PROXY) //这里重点

我们可以看下效果,配置前后对于一般的抓包还是很有效果的(右侧配置Proxy.NO_PROXY)。

密钥信息安全

加解密使用的密钥应该是安全中的安全,如果这个被别人知道了,那你数据的安全等于是白做了,所以如何保持密钥信息也是很重要的。

1. 底层存储

这是一种常见的存储方式,相对安全。主要就是通过JNI实现,将密钥通过底层C保存同时校验应用的签名

2. 网络存储

对于通用的接口,我们可以把密钥信息保存在程序中即可。涉及到用户信息以及交易信息的接口我们可以将密钥信息保存在后台服务器上,在用户登录后下发到客户端。如下:

二次打包

有反编译经验的同学应该都了解,没有经过加固的应用很容易被别人反编译以后二次打包。那这种我们常用的方式就是将一些核心功能的调用前校验应用的签名(JNI底层校验),特别是应用启动时候来校验应用签名是否正确,可以参考这篇文章实现android jni签名验证

代码混淆

代码的混淆还是很有必要的,虽然配置起来很麻烦,偶尔还会因为混淆的问题出现问题(特别是新增加功能后忘记配置混淆)。代码混淆以后加大了他人反编译以后阅读业务逻辑的难度,从而让你的应用更安全。

应用加固

应用的加固在你上传应用宝或者其他商店基本都是必须做的事情,常用的就360加固网易易盾百度加固爱加密等,当然你是付钱越多加密的越安全了。

以上就是自己根据平时经验总结的一些安全知识,希望对大家有帮助。

posted @ 2021-07-09 03:34  拜雨  阅读(292)  评论(0编辑  收藏  举报