如今移动客户端与服务器端的安全通信问题越来越重要,市面上大多公司所采用的解决方案也层出不穷,大多只是采用简单的对称加密算法对某些敏感字段进行加密,使用HTTPS
的还是很少的。
分工合作:
权政龙 | 李积恩 | 毛俊杰 | 黄仪标 |
---|---|---|---|
负责跟进 https server 的方案 | 合作完成可用技术方案 | 协调整个方案进展 | 撰写技术文档、写 sequence、合作完成可用技术方案 |
调研
下面是调研的部分公司移动端与服务端的安全通信所采用的方案:
App 名称 | 方案 | 安全系数 |
---|---|---|
Nice | 只支持 HTTP,采用加盐方式加密敏感字段,只改篡改,不防读。其中,算法是用纯 C 写的,编译成.so 库文件放在工程中,加大防反编译的难度。 | 安全系数一般,只防改不防读 |
去哪儿 | 只支持 HTTP,采用设备 UUID 作为固定 key 加密请求参数,然后将加密串转换成二进制,整体传输到服务端。 | 安全系数一般,只要知道固定的 key 就可以解密,但是可以透明化我们的参数,即使拆包也看不出有哪些字段 |
58 同城 | 只支持 HTTP,只是对敏感字段进行 AES 加密,登录后返回一个 uid 和 tokenid | 安全系数一般 : |
爱鲜蜂 | 只支持 HTTP,只对敏感字段对称加密,雅虎的几个后台大牛认为只要后台足够牛逼,就可以检测到请求的异常并迅速作出处理。当出现异常时,立即将 token 效率。 | 安全系数主要是依赖后台的检测异常能力 |
美容总监 | 只支持 HTTP,敏感字段对称加密,并采用加盐的方式防篡改。服务端返回客户端的数据都是明文 | 安全系数一般,对于服务端返回客户端的数据,如果是支付相关的数据理应加密处理,防篡改防读取 |
At | 只支持 HTTP,敏感字段对称加密,并采用加盐的方式防篡改。 | 安全系数一般,防篡改防读取 |
鉴于公司对移动客户端与服务器端的安全通信的重视程度和要求,向业界 ios 大牛唐巧咨询过相关安全问题,其建议采用加盐和对称加密已经是很安全的了。
以上只是调研的部分信息。
移动端与服务端现状
当前患者端和医生端都存在同样的现状,下面指出几点关键点:
- 登录、注册接口明文传输
- 未添加登录时效性处理,一旦登录可一直存在
- 没有处理一天的登录出错次数限制
- 支付相关的接口,服务端将订单相关数据返回到客户端是没有加密的,如果拦截篡改订单信息那就很危险了。
准备方案
参考 2015 年 12 月 10 日关于账号安全及通信安全的方案评审会的基本结论,下面是黄仪标、李积恩、毛俊杰共同讨论得出的方案:
-
普通登录接口采用
HTTPS
。公钥放在服务端,由服务端提供下载公钥的接口。客户端判断公钥文件是否存在或者是否过期,如果过期或者不存在,则调用接口下载。然后,再调用登录接口。登录前,由移动端生成Random Key
作为参数一起提交到服务端,服务端记录下Randowm Key
作为解密。服务端返回Token
及userid
-
快速登录接口采用
HTTP
。Random Key
+手机号+短信验证码。服务端返回token
及userid
列表 -
对于支付相关的接口,有两种方式:一种是使用
HTTPS
的方式,另一种是使用HTTP
,但是对返回值采用Random Key
加盐的方式加密防篡改 -
对于展示型数据接口,只对接口参数采用
Random Key
加盐对称加密方式,对于服务器响应的数据,没有必要加密。
为了提供安全系数,对于
Random Key
可以使用公钥加密再传输到服务端,服务端使用私钥解密就可以得到Random Key
HTTPS 服务流程
如下图为HTTPS
请求流程图解:
分为以下步骤:
- 客户端:发起
HTTPS
请求 - 服务端:采用 HTTPS 协议的服务器必须要有一套数字证书,可以自己制作,也可以向组织申请。区别就是自己颁发的证书需要客户端验证通过,才可以继续访问,而使用受信任的公司申请的证书则不会弹出提示页面。这套证书其实就是一对公钥和私钥。
- 服务端:传送证书到客户端,这个证书也就是公钥
- 客户端:解析证书,得到公钥,验证有效性。然后生成
Random Key
,并使用公钥加密Random Key
。 - 客户端:传输使用公钥加密后的
Random Key
到服务端 - 服务端:使用私钥解密得到
Random Key
,然后使用Random key
加密内容 - 服务端:将加密的内容返回给客户端
- 客户端:使用第四步生成的
Random Key
解密,得到响应的内容
登录流程
对于普通登录是采用HTTPS
来访问数据,因此,我们的流程是这样的:
- 客户端:当无公钥时,发请求下载公钥
- 客户端:生成
Random Key
,使用公钥加密,连同账号、密码一起发送到服务端 - 服务端:使用私钥解密得到
Random Key
并验证账号密码是否正确,存储或者更新Random Key
- 服务端:服务端生成
Token
及userid
响应给客户端 - 客户端:记录下
token
及userid
普通 HTTP 接口访问流程
- 客户端:对所有敏感字段值加密(非敏感字段不用加密)
- 客户端:对参数拼接+
Random key
一起采用特定的算法加密生成salt
- 服务端: 服务端采用同样的方式生成
salt
确认签名正确 - 服务端:若响应的数据有敏感信息,用参敏感字段拼接+
Random Key
生成salt
,防篡改,但是不防读。
注意:对于响应数据不需要所有字段都参于生成
salt
,只需要将指定的敏感信息拼接+随机 key 一起拼接就可以了
服务端检测接口访问有效性
-
当接口参数中的
salt
与服务端经过拼接所生成的salt
不一致时,服务端应该视为异常,将自动将token
和Random Key
清空,那么再访问时就要求重新登录了。 -
当
Token
过期时,服务端要求先登录
方案安全性分析
-
Random Key
只是在登录时才可以通过网络传输,而且这个Random Key
是通过公钥加密的,因此安全性可保证,后续的接口中都不需要再传输这个Random Key
-
Token
是在登录成功后服务端返回,后台的接口中都要求传此参数,服务端用于检验用户登录有效期是否已过 -
登录时密码对称加密,且使用
salt
加盐方式可防止信息篡改 -
对于支付类接口若是使用 HTTP 请求,响应数据生成
salt
来防止数据篡改。对于响应字段,可以不加密。 -
对于普通展示数据的接口,不需要加密,也可以加密。
注意:如果服务端希望统一接口,那么可以在所有的接口中都统一使用
salt
防篡改。
推荐加密算法
- 生成
salt
算法规则,可以使用所有请求参数拼接+Random key
一起md5
或者AES
。 - 对于敏感字段可以统一使用
md5
或者AES
加密。
注意:生成
salt
规则一定要与服务端统一,对于空值和null
值是否参予salt
一定要定清楚。