发布于 

商城系统 前后端交互 报文安全性问题 方案设计

H5商城作为面向互联网的系统,在客户端与服务端通信时需要考虑报文安全性问题,在此对实践中采用的其中一些设计方案做一个总结和介绍。

商城系统在功能定位上需要用户通过互联网访问并完成业务逻辑操作,因此,系统在交互安全性上做出额外设计,描述如下。

  1. 客户端(包含H5客户端以及Web端)与后台服务均通过Https协议进行交互;

    HTTPS (全称:Hypertext Transfer Protocol Secure ),是以安全为目标的 HTTP 通道,在HTTP的基础上通过传输加密和身份认证保证了传输过程的安全性。HTTPS 在HTTP 的基础下加入SSL,HTTPS 的安全基础是 SSL,因此加密的详细内容就需要 SSL。 HTTPS 存在不同于 HTTP 的默认端口及一个加密/身份验证层(在 HTTP与 TCP 之间)。这个系统提供了身份验证与加密通讯方法。它被广泛用于万维网上安全敏感的通讯,例如交易支付等方面 。

  2. 客户端的绝大多数操作均须检查用户登录状态,若未登录则直接拒绝;
  3. Web端的绝大多数操作均会校验登录用户的角色和权限,避免越权操作;
  4. 对于敏感字段,如登录密码,使用RSA非对称加密方式进行加密传输;
  5. H5客户端与后台的交互,在Https的基础上,使用随机密钥对请求和返回报文进行对称加密(密钥交换和维护逻辑见下述);
  6. H5客户端与后台之间,增加网关服务,对请求进行登录状态校验、报文解密、签名校验、防重放攻击以及限流等操作,只将合法请求路由到后台服务(签名校验逻辑见下述);
  7. 其他

H5客户端与后台服务间报文加解密设计

商城-报文加解密-时序图
参考时序图,客户端与商城网关和后台服务间交互、密钥交换和加解密逻辑如下:

  1. 用户由前置系统(公众号)进入商城页面时,需要在URL后携带加密用户信息(具体参考《用户体系设计-客户登录》)
  2. 【客户端】商城客户端页面获取到加密用户信息,生成随机密钥Key,并将Key作为登录请求报文的一个字段
  3. 【客户端】使用Rsa(或SM2)公钥对登录请求报文加密,并通过时间戳和随机数对请求报文生成签名字符串
  4. 【客户端】将签名字符串作为header,将加密请求报文作为body,请求登录接口
  5. 【网关】拦截登录请求,使用Rsa(或SM2)密钥对请求报文进行解密,若解密失败直接返回错误信息
  6. 【网关】对请求报文做签名,并与header中的签名字符串做比对,若比对不通过,则直接返回错误信息,若通过,则将请求转发到后台服务
  7. 【后台】对收到的报文做处理,校验登录信息是否正确,执行登录操作,生成随机token,并将token和对应的用户信息保存到缓存,返回登录成功信息
  8. 【网关】监测到登录成功,从返回报文中获取到token和Key,将token和key保存到缓存中,并使用Key加密返回报文,将加密后报文返回给客户端
  9. 【客户端】获取到返回报文,使用Key解密报文,取出token
  10. 【客户端】后续的请求中均将token作为header项携带,并使用Key对请求报文进行加密,且做报文签名
  11. 【网关】拦截请求,获取token,校验登录状态,若token已失效,则直接返回错误
  12. 【网关】若token有效,从缓存中获取对应的Key,使用该Key解密请求报文,并进行签名校验,校验失败则直接返回错误信息,通过则转发请求至后台服务
  13. 【后台】后台服务正常处理业务逻辑,返回明文报文
  14. 【网关】网关使用Key对返回报文进行加密,将加密报文返回给客户端
  15. 【客户端】使用Key解密返回报文,获取到结果

接口签名设计

接口签名设计主要用于防止抓包后重放攻击。设计思路为:
客户端在请求时,执行以下操作

  1. 在拼接完业务请求(json格式)后,先获取当前的时间戳timestamp,并随机生成一个字符串nonce,
  2. 将timestamp和nonce作为请求体的一部分,拼成完整的请求body;
  3. 使用MD5(body+appSecretKey+timestamp+nonce)计算出签名值sign
  4. 将sign置入请求header中

服务端(网关)收到请求后,执行一下操作

  1. 解密请求报文,获取到body(若解密失败则直接返回异常),从body中获取到timestamp和nonce;
  2. 校验timestamp与当前服务器时间是否相差10分钟以上,若是则拒绝请求;
  3. 校验nonce在缓存中是否存在,若存在则拒绝请求,若不存在,则将nonce写入缓存,10分钟失效;
  4. 计算MD5(body+appSecretKey+timestamp+nonce),与header中的sign比较,若不匹配则拒绝请求,若匹配则正常处理请求;

其中,appSecretKey为分配给客户端的一串密钥字符串。

在这个过程中,对于高级攻击者,可能通过逆向工程获取到前端接口签名逻辑,获取到appSecretKey,从而伪造请求,由于h5客户端暴露在公网,无法完全避免逆向工程,因此本设计主要旨在增加攻击难度、提高攻击门槛