关于支付密码安全(通信安全):
代码语言:javascript复制对于一些强敏感数据, 例如手机号,银行卡号,密码,cvv,我们需要做一些加密。
RSA和AES(对称性加密) 两套加密方式对数据进行加密:
首先我们会随机生成x位的随机密钥, 要加密的数据data用该随机密钥去加密,最后将密钥进行Base64位编码,此时的数据才是我们要上传到服务器的敏感数据, 大家都知道AES是一个对称加密算法, 服务器端必须知道密钥才能解密..
对的 ,新问题出现了, 服务器端怎么才能知道我们的这个随机密钥呢?,这个时候我们还需要吧随机密钥进行RSA(非对称性加密),进行RSA加密的时候,我们只需要用到公钥即可,然后base64编码,上传到服务器,这个时候服务器根据已有的私钥,就可以进行解密,从而拿到了随机密钥,然后再去根据随机密钥把我们的重要数据解密, 要注意的是, 不管是AES还是RSA 都需要进行Base64编码处理后,再去上传服务器,因为两种加密算法,出来的都是二进制流,在转化成字符串的时候可能出现空格造成数据的截断, 所以必须编码一下不要让他出现空格。
但是 ,RSA 加密解密对性能开销较大, 所以不建议大量使用,以增加服务器端压力。
RSA 对加密的数据长度有限制, 具体长度是与RSA密钥位数有关系,所以对于比较长的数据,没法加密
AES (对称性加密),前端获取一个随机密钥,对数据进行AES(对称性加密),然后进行base64位编码,因为AES加密完成之后是二进制流,转化成字符串的时候可能会因为空格造成数据截断,所以要进行base64编码, 然后上传到服务器, 这个时候服务器是不知道这个随机密钥的,我们就需要告诉他, 但是这个我们也要进行加密(根据参数不同来设置),这个加密算法叫做 RSA 是一个非对称性加密的算法, 我们前端拿到公钥对随机密钥进行加密,然后传输服务器, 服务器有他自己的私钥,进行解密,拿到密钥值,然后对我们的敏感数据AES进行解密,从而完成安全的数据传输,而服务器要保证的就是这个RSA的密钥不被泄露即可。
应用加固(应用安全):
应用加固包括,防注入、防纂改、反调试,病毒扫描(云扫描);
防注入:
注入就是指的当前APP进程呗其他程序使用特定的方法(ptrce,Dlopen等)插入不属于当前APP 的模块,这些模板一般都是具有特殊的行为, 如收集App的隐私数据, 使用Hook等方法劫持app的正常运行流程等,其中Hook是最主要的安全风险。
防native注入的方法是:通过app 进程空间,查看加载的库是不是都在/system或/data/data/app底下,如果不是,则一定有注入。
反篡改:
传统判断app是否盗版的方法, 业界惯用的做法是事先收集大量的正版应用信息去做白名单,然后利用当前app的包名、签名等信息去做匹配, 该方法的准确度依赖于白名单库的大小,并且需要网络连接,但是现在我了解到一种新型的防纂改、重打包的方法, 那就是,我们的签名信息是唯一的,生成的hashcode值也肯定是唯一的,我们通过jni编写so动态库,在软件启动时去动态的判断,现在app的签名是否同我们打包发布时的签名一致,如不一致,则强行退出。
反调试:
调试指的就是当前的app被其他程序使用特定的方法(调试器,ptrace )跟踪劫持,被调试后的app的一切行为都可以被其他程序查看和修改,大家可以联想一下平时通过gdb调试程序。
反调试 功能分为两个步骤, 首先检测当前app是否正在被调试, 如果app正在被调试的话,则返回调试器所在进程的进程名字。
这些东西像第三方已经做的非常好了,他的底层其实就是有两种方式, 一个是内核里有一个调试的debug选项关掉,但是作为app我们没办法去改变内核的东西, 另一个就是双进程实现反调试, 又叫守护线程(与保护app不被杀死原理一致(5.0 以后部分手机实现双杀,例如小米)),我们知道一个进程只允许有一个调试器, 所以在进程起来的同时, 会fork一个daemon(守护进程)并跟踪被保护的app进程, 守护进程会实现拦截调试器的入口,保证其他程序无法调试当前app,守护进程一旦激活,就会一直存在,直到当前应用退出, 如果强行关闭守护进程,当前app也会随之关闭, 这里要注意信号的处理。
防止重打包;
每一个apk都会有个签名,签名只有这个开发者才拥有,如果别人修改了代码,也必须要签名才能运行,但是修改者的签名与官方签名是不一致的,我们在so里面存储了应用程序官方签名的hashcode值,在应用启动后so就会检查签名是不是官方的签名,如果不是,应用程序直接关闭退出,亦或是抛出一个异常,一般来说将对比的代码放在动态库中比较好。