五叶神
五叶神
  • 发布:2017-08-23 17:01
  • 更新:2020-03-11 14:48
  • 阅读:13980

【交流分享】Dcloud开发APP心得系列之接口安全加密篇

分类:HTML5+

================ 补充 ====================

此方法已被 @wenju 大神验证无效,仅作参考,还是开启混淆 js吧

==============================================================================

继代码性能优化篇再来一波。。。

使用Dcloud开发APP以来大家讨论关注比较多的问题估计就是APP代码安全性问题,很多人都在考虑加密、代码混淆啊,因为打包好的apk、ipa可以直接解压从中找到完整的页面文件,包括HTML、css、js代码等,怕怕。。。这样另有目的的人会不会直接copy你的代码打包新的APP?

其实我觉得那些静态页面根本就不值钱,就像web网页一样,照样能扒下所有的静态文件。打包时使用代码混淆功能感觉也得不偿失,消耗资源,影响APP性能。整个APP里面其实唯一值得保护的就只有manifest.json文件里面的sdk配置以及你的后台API数据接口,manifest.json文件配置Dcloud已经处理过了,所有是相对安全的。

能看到你的代码就能使用你的接口,那怎么保证你的接口数据是安全的?提供一个解决方案:

1、用户信息的储存

用户登录后存储用户唯一标识userkey加密串至localStorage,后续所有的用户相关数据获取传userkey参数获取。

2、接口签名认证机制

接口除传正常参数外再补加几个加密用参数:
timestamp:时间戳,获取客户端当前时间,如果时间差与服务器超过五分钟,则请求失败
appkey:签名appkey
sign:接口签名参数,使用md5摘要算法处理一定规律的字符串,所有接口需要参数 + timestamp + appkey + 按参数名排序后拼接成字符串(参数名+值)+ appsecret;

封装成一个统一处理接口data参数的方法

app.md5Data=function(oldData){  
    var data=JSON.parse(JSON.stringify(oldData||{})) //保存原始数据  
    data.appkey=appkey;  
    data.timestamp =new Date().toUTCString();    //**由于国外访问存在时差,会导致时间戳验证失败,故此处改为UTC标准时间,服务端处理转换**  
    var keys=[];  
    for(var k in data){  
        if(data[k]===0||data[k]===false||data[k]){  
            keys.push(k);  
        }else{  
            delete data[k]; //剔除空参数  
        }  
    }  

    keys=keys.sort();  
    var signStr='';  
    for(var i=0; i<keys.length; i  ){  
        signStr =keys[i].toLowerCase()+data[keys[i]];  
    }  

    data.sign=md5(signStr+appsecret);  
    return data;  
}

处理后的data为:

{  
    pageno: page,  
    pagesize: 20,  
    userkey: userkey,  
    type: type,  
    timestamp:'2017-08-23 16:39:50',  
    appkey:'.....',  
    sign:'A765E24767546E1109B5576538C87FF6'  
}  

mui.ajax({  
    data:app.md5Data({ .... })  
})

后台进行同样的方式生成sign,如果配对不一致则请求失败。

那么问题又来了,appkey、appsecret存储在哪里?肯定不能直接写死在js中,那样就没意义了,目前采用的方法是获取manifest.json配置的某个第三方sdk的appid,appkey,最后发现只有个推的配置信息是提供了方法获取的,果断使用plus.push.getClientInfo().appkey 、appsecret获取配置文件中的值(解压是获取不到sdk配置的)。

当然也可以直接写了上述方法的js文件打包的时候启用js原生混淆,这样明文写死也没有关系,解压打开你的app.js看到的全是乱码,只是不支持安卓4.0以下手机。

补充:没有提供获取方法的sdk配置也是可以通过native.js获取到(真不知道安不安全),方法链接: https://ask.dcloud.net.cn/article/488

这样就算别人拿到你的源码,也无法请求到你API接口的任何数据。

注:目前只想到这个方法存储appkey、appsecret,或许大家有更靠谱的方法存储,欢迎交流。

代码精简、性能优化篇

7 关注 分享
lhyh DCloud_heavensoft Trust uniapper Marco 3***@qq.com 绿萝根

要回复文章请先登录注册

青椒茄子

青椒茄子

回复 五叶神 :
无论你怎么签名,签名方式你还得保存在你客户端中,别人一解压,一看不就知道了,做了这么年的游戏和APP,代码层面从来都是混淆加密,增加破解难度,对于你说的api请求,需要用到token,在服务端校验api访问权限,根本不是一回事
2018-07-10 13:43
五叶神

五叶神 (作者)

回复 青椒茄子 :
MD5算法可以说是不可逆转的,前后台配合都使用约定好的规则组装出同样的字符串用MD5处理后对比,每次请求的参数五分钟失效,这是签名机制,简单又实用,如果连这个都不做别人就可以直接请求你的api了
2018-07-09 16:35
青椒茄子

青椒茄子

其实官方文档说得很明白,加密都是在后台进行,前台做任何加密都显得鸡肋,最多就是增加下别人破解的难度;
2018-07-03 09:17
五叶神

五叶神 (作者)

回复 前端攻城师 :
那就用你这个推送的key作为 appkey加密用就行了啊,跟后台加密的对应的就行了,跟你随便自己乱填的key不是一样的用
2018-06-27 10:12
前端攻城师

前端攻城师

那要是我用到推送,还有啥方式可以存appkey啊
2018-06-22 15:32
1***@qq.com

1***@qq.com

回复 五叶神 :
好的 谢谢大神
2017-09-29 10:04
五叶神

五叶神 (作者)

回复 1***@qq.com :
真机调试 manifest.json配置的东西全部都是基座默认的,打包以后才会生效,所以调试的时候写死就行了,打包的时候再替换成plus.push.getClientInfo().appkey
2017-09-29 09:17
1***@qq.com

1***@qq.com

大神 你能告诉我plus.push.getClientInfo().appkey是怎么获取的么,为什么我先随便配置了一个个推appkey,然后console.log出的appkey不是我配置的?而是一堆不知道什么玩意儿,求教
2017-09-28 18:30
uniapper

uniapper

mark
2017-08-30 12:03
五叶神

五叶神 (作者)

回复 wenju :
接口是会提示errormsg的,‘非法的时间戳参数’,请修正手机时间之类的,所有错误肯定都会抛出异常信息的
2017-08-24 11:26