如今移动客户端与服务器端的安全通信问题越来越重要,市面上大多公司所采用的解决方案也层出不穷,大多只是采用简单的对称加密算法对某些敏感字段进行加密,使用HTTPS的还是很少的。

分工合作:

权政龙李积恩毛俊杰黄仪标
负责跟进 https server 的方案合作完成可用技术方案协调整个方案进展撰写技术文档、写 sequence、合作完成可用技术方案

调研

下面是调研的部分公司移动端与服务端的安全通信所采用的方案:

App 名称方案安全系数
Nice只支持 HTTP,采用加盐方式加密敏感字段,只改篡改,不防读。其中,算法是用纯 C 写的,编译成.so 库文件放在工程中,加大防反编译的难度。安全系数一般,只防改不防读
去哪儿只支持 HTTP,采用设备 UUID 作为固定 key 加密请求参数,然后将加密串转换成二进制,整体传输到服务端。安全系数一般,只要知道固定的 key 就可以解密,但是可以透明化我们的参数,即使拆包也看不出有哪些字段
58 同城只支持 HTTP,只是对敏感字段进行 AES 加密,登录后返回一个 uid 和 tokenid安全系数一般 :
爱鲜蜂只支持 HTTP,只对敏感字段对称加密,雅虎的几个后台大牛认为只要后台足够牛逼,就可以检测到请求的异常并迅速作出处理。当出现异常时,立即将 token 效率。安全系数主要是依赖后台的检测异常能力
美容总监只支持 HTTP,敏感字段对称加密,并采用加盐的方式防篡改。服务端返回客户端的数据都是明文安全系数一般,对于服务端返回客户端的数据,如果是支付相关的数据理应加密处理,防篡改防读取
At只支持 HTTP,敏感字段对称加密,并采用加盐的方式防篡改。安全系数一般,防篡改防读取

鉴于公司对移动客户端与服务器端的安全通信的重视程度和要求,向业界 ios 大牛唐巧咨询过相关安全问题,其建议采用加盐和对称加密已经是很安全的了。

以上只是调研的部分信息。

移动端与服务端现状

当前患者端和医生端都存在同样的现状,下面指出几点关键点:

  1. 登录、注册接口明文传输
  2. 未添加登录时效性处理,一旦登录可一直存在
  3. 没有处理一天的登录出错次数限制
  4. 支付相关的接口,服务端将订单相关数据返回到客户端是没有加密的,如果拦截篡改订单信息那就很危险了。

准备方案

参考 2015 年 12 月 10 日关于账号安全及通信安全的方案评审会的基本结论,下面是黄仪标、李积恩、毛俊杰共同讨论得出的方案:

  1. 普通登录接口采用HTTPS。公钥放在服务端,由服务端提供下载公钥的接口。客户端判断公钥文件是否存在或者是否过期,如果过期或者不存在,则调用接口下载。然后,再调用登录接口。登录前,由移动端生成Random Key作为参数一起提交到服务端,服务端记录下Randowm Key作为解密。服务端返回Tokenuserid

  2. 快速登录接口采用HTTPRandom Key+手机号+短信验证码。服务端返回tokenuserid列表

  3. 对于支付相关的接口,有两种方式:一种是使用HTTPS的方式,另一种是使用HTTP,但是对返回值采用Random Key加盐的方式加密防篡改

  4. 对于展示型数据接口,只对接口参数采用Random Key加盐对称加密方式,对于服务器响应的数据,没有必要加密。

为了提供安全系数,对于Random Key可以使用公钥加密再传输到服务端,服务端使用私钥解密就可以得到Random Key

HTTPS 服务流程

如下图为HTTPS请求流程图解:

image

分为以下步骤:

  1. 客户端:发起HTTPS请求
  2. 服务端:采用 HTTPS 协议的服务器必须要有一套数字证书,可以自己制作,也可以向组织申请。区别就是自己颁发的证书需要客户端验证通过,才可以继续访问,而使用受信任的公司申请的证书则不会弹出提示页面。这套证书其实就是一对公钥和私钥。
  3. 服务端:传送证书到客户端,这个证书也就是公钥
  4. 客户端:解析证书,得到公钥,验证有效性。然后生成Random Key,并使用公钥加密Random Key
  5. 客户端:传输使用公钥加密后的Random Key到服务端
  6. 服务端:使用私钥解密得到Random Key,然后使用Random key加密内容
  7. 服务端:将加密的内容返回给客户端
  8. 客户端:使用第四步生成的Random Key解密,得到响应的内容

登录流程

image

对于普通登录是采用HTTPS来访问数据,因此,我们的流程是这样的:

  1. 客户端:当无公钥时,发请求下载公钥
  2. 客户端:生成Random Key,使用公钥加密,连同账号、密码一起发送到服务端
  3. 服务端:使用私钥解密得到Random Key并验证账号密码是否正确,存储或者更新Random Key
  4. 服务端:服务端生成Tokenuserid响应给客户端
  5. 客户端:记录下tokenuserid

普通 HTTP 接口访问流程

image

  1. 客户端:对所有敏感字段值加密(非敏感字段不用加密)
  2. 客户端:对参数拼接+Random key一起采用特定的算法加密生成salt
  3. 服务端: 服务端采用同样的方式生成salt确认签名正确
  4. 服务端:若响应的数据有敏感信息,用参敏感字段拼接+Random Key生成salt,防篡改,但是不防读。

注意:对于响应数据不需要所有字段都参于生成salt,只需要将指定的敏感信息拼接+随机 key 一起拼接就可以了

服务端检测接口访问有效性

  1. 当接口参数中的salt与服务端经过拼接所生成的salt不一致时,服务端应该视为异常,将自动将tokenRandom Key清空,那么再访问时就要求重新登录了。

  2. Token过期时,服务端要求先登录

方案安全性分析

  1. Random Key只是在登录时才可以通过网络传输,而且这个Random Key是通过公钥加密的,因此安全性可保证,后续的接口中都不需要再传输这个Random Key

  2. Token是在登录成功后服务端返回,后台的接口中都要求传此参数,服务端用于检验用户登录有效期是否已过

  3. 登录时密码对称加密,且使用salt加盐方式可防止信息篡改

  4. 对于支付类接口若是使用 HTTP 请求,响应数据生成salt来防止数据篡改。对于响应字段,可以不加密。

  5. 对于普通展示数据的接口,不需要加密,也可以加密。

注意:如果服务端希望统一接口,那么可以在所有的接口中都统一使用salt防篡改。

推荐加密算法

  1. 生成salt算法规则,可以使用所有请求参数拼接+Random key一起md5或者AES
  2. 对于敏感字段可以统一使用md5或者AES加密。

注意:生成salt规则一定要与服务端统一,对于空值和null值是否参予salt一定要定清楚。