一、引言
客户端安全是一个很容易被大家忽视的问题,随着用户越来越多的把隐私毫无保留的交给各式各样的APP,特别是有一些还涉及到金融财产,那么我们作为客户端开发从业者,就不得不为了用户多着想,多建立一些客户端的安全保障。
安全是极难做到100%的,更多的情况是道高一尺魔高一丈,但是尽量多的安全保障,可以让别人的破解成本指数级的提高,直至让人觉得破解你的客户端性价比太低了。还是那句话,如果你和另一个人在野外遇到一头豹子,你想要逃生,不需要跑的比豹子快,只需要跑的比另一人快就够了。
如果想偷个小懒,又不差钱,其实市面上有很多不错的第三方安全加密服务商,直接用他们的服务,达到的效果远超自己两三杆枪折腾几个月所能达到的效果。但是有得必有失,如果要说缺点,就是因为他们的服务对客户端的侵入性太强,所以时不时的会给你一个“惊喜”,比如每次发布新的操作系统版本,或者新的手机时,都有一定的可能会造成兼容性问题,直接黑屏闪退等等。那怎么衡量用不用第三方呢?烫爷觉得,如果你们的客户端本身比较纯净,(所谓纯净就是没有其他太多重量级的框架),那大可以放心一用,出了问题,提交给第三方,反应还是很积极的;如果本身已经有了一些复杂的带有侵入性的框架,那能不用可能还是别用了,几个大框架交织在一起所碰撞出来的各种火花,估计你的小心脏承受不了。
此外,iOS由于系统封闭,相对安全一些,所以部分安全措施只需要在安卓平台考虑,下面就不做特殊说明了。
二、接口安全
HTTPS
HTTPS不再像以前那样是少数金融APP的专利了,特别是iOS从9.0开始默认采用HTTPS,HTTPS基本成为了标配。加密算法
如果光用HTTPS还不够放心,那你也可以用自己的密钥再对接口中的敏感信息进行加密。加密时非对称、对称加密算法最好配合使用,这样既能利用到非对称加密算法的安全性,又能避免其加密内容太长时的性能问题。一般做法是用RSA算法加密传输AES算法的密钥,然后用AES算法加密具体信息。deviceID和Token
大多数情况下,我们需要获取唯一设备号,方便数据统计,以及和用户名密码关联生成token。iOS因为安全原因,已经无法正确获取uniqueIdentifier和MAC地址,而安卓因为生态过于繁杂,在某些机型上取imei、mac也经常会存在问题,所以在两个平台都可以用一个非常偷懒的方法,即直接在本地生成一个UUID作为deviceId并缓存起来。
服务器结合deviceID、用户名密码、时间戳等生成一个token,返回给客户端,之后客户端每次请求必须把token放在http头里返给服务器,这样服务器才会受理请求,返回信息。此外token还应根据自身情况设计一个失效机制,比如2周内没访问过就失效。
三、包安全
验证包完整性
由于安卓市场的鱼龙混杂和安卓平台的开放性,很容易就被一些不法分子利用,反编译后植入后门代码再重新打包给无知群众使用,以从中牟利。所以我们很有必要去验证包的完整性。这里有几个思路,一是验证签名,二是验证dex文件,三是验证apk,具体的验证可以使用CRC32、MD5这类数据摘要算法。
一个必须要注意的点是如果把用于比对的正确值存放在本地java代码中,就很容易被黑客反编译利用,即使用接口从服务器去获取这些数据,相关的验证代码也很有可能被反编译后去除,那么比较稳妥的做法是把安全验证和必要的初始化过程捆绑起来放在so的C++代码中去处理,通过 JNI 进行调用,这样黑客就没那么方便反编译和绕过安全验证相关代码了。防动态注入
比较简单省事的方案是在进行安全验证时检查手机是否root,并检查进程中是否有常见的hook工具如Cydia Substrate或者Xposed等,如有,则提醒用户并直接关闭客户端。加壳
对于apk来说,只要能反编译,那么花上足够多的时间和耐心,总归可以慢慢破解,那么更有效的方案就是给apk加壳了。所谓加壳,简单说就是把要加壳的目标apk加密,然后在外面再套一层壳apk,在使用时壳apk负责解密原apk,并通过DexClassLoader动态加载。整个过程还是有点复杂的,索性网上相关的文章不少,有兴趣可以去搜来参考。
四、系统安全
自定义键盘
系统自带的键盘很可能会被劫持,所以大多数涉及钱的app都很有必要写一个自己的键盘组件。特别是输入密码所用的键盘,最好还能随机生成数字的位置。防截屏
黑客很有可能控制手机,偷偷的给APP截屏,这样你的屏幕上有敏感信息时,比如每次输入密码会有短暂的字母显示,就会暴露,这时候就需要有防截屏的功能。谷歌自己就提供了这个功能,只需要在每个Activity的setContentView()方法前加上下面这段代码就可以了:
getWindow().setFlags(LayoutParams.FLAG_SECURE, LayoutParams.FLAG_SECURE);
五、业务安全
验证码
这个其实不用多说,大多数涉及到钱的操作,最后一步用短信验证码已经算行业标准了。如果连这个都没做到,那就只能自求多福了。同卡进出
同卡进出就是指资金与银行卡完全绑定,确保从哪里投资就回到哪里去,实现资金的闭环。同卡进出可以最大限度保障资金安全,即使发生盗刷,资金最终还是只能在同一张银行卡内流转,骗子无法取走。AI
AI就比较高大上了,但这一定是未来的趋势。金融公司可以通过人工智能和机器学习逐步建立和完善风险识别模型。比如国内某大型第三方支付公司就通过账户、身份、交易、行为、关系、设备、位置、偏好8个维度进行风险扫描,识别并拦截了大量的盗刷行为。目前,其资损率为十万分之一,远好于Paypal的千分之二。而对于大多数没有实力自己组建类似平台的公司,也可以通过引进第三方风控系统来进行主动防御。
总之,客户端安全是永无止境的,我们每多做一点点防范,黑客破解的难度就会增高一点点,客户的财产安全也会更有保障一点点,关键还是在态度。