如何保证APP与API通信安全,TOKEN冒用带来的风险很大?

TOKEN作为用户身份凭证并不能保证数据安全 , 别人通过抓包等方式很容易拿到TOKEN , 带上TOKEN请求我们的API接口就能获取数据;其实换一个角度想:我们只需保证即使TOKEN被别人冒用 , 也不能调用我们API接口就行 。
分享一个前后端使用AES和RSA混合加密通信的方案 。
AES对称加密首先看一下AES加密的示意图:

如何保证APP与API通信安全,TOKEN冒用带来的风险很大?

文章插图
加密过程为:发送方(App)使用密钥对参数明文进行AES加密获得密文 , 然后将密文和密钥一起发给接收方(服务端) , 接收方使用密钥对密文进行AES解密 , 得到参数明文 。
AES由于是对称加密算法 , 特点就是加解密运算速度快;由于加解密使用的是同一个密钥 , 所以缺点就是在传输过程中会存在密钥泄露的风险 。
RSA非对称加密同样的 , 先来看一下RSA加密的示意图:
如何保证APP与API通信安全,TOKEN冒用带来的风险很大?

文章插图
首先接收方(服务端)生成一对RSA密钥(公钥、私钥) , 私钥自己保存同时公钥公布给发送方(APP) 。
加密过程:发送方使用接收方公钥将参数明文进行RSA加密得到密文 , 并将密文发送给接收方 , 接收方使用自己的私钥对密文进行RSA解密得到参数明文 。
同样的 , 服务端返回数据给APP时也可以使用私钥对数据进行签名 , APP可以使用服务端的公钥来验证签名 , 从而判断数据是否来自合法的服务端 。
RSA是非对称加密算法 , 加解密大量数据速度较慢 , 但由于加解密使用不同的密钥 , 所以安全度较高 。
介于这两种加密方式各有优缺点 , 所以前后端加密通信方案通常采用AES对称加密算法对参数进行加密 , RSA非对称加密算法则只用来对AES密钥进行加密 , 两种加密方式混合使用既不会太影响通信速度 , 又保证了通信安全 。
为了防止重放攻击 , 我们还需要在AES+RSA混合加密的基础上再加入时间戳、随机字符串以及数字签名等校验逻辑 。
为了防止中间人攻击 , 首先HTTPS是必须的 , 除此之外前后端还需要互相进行身份认证 , 确保通信没有被劫持 。
前后端加密通信完整流程准备工作:服务端生成RSA密钥对(公钥、私钥) , 公钥下发给APP , 自己持有私钥;APP也需要生成RSA密钥对(公钥、私钥) , 公钥上传到服务端保存、私钥自己保留 。
首先展示一下我用代码实现的前后端完整的加解密通信流程:
如何保证APP与API通信安全,TOKEN冒用带来的风险很大?

文章插图
首先讲一下APP调用接口时的加密流程:
  1. 随机生成一个AES加密算法的密钥 , 用于后续加密;
  2. 使用服务端的RSA公钥对步骤1中生成的AES密钥明文进行RSA加密生成密钥密文;
  3. 使用AES密钥明文对参数明文进行AES加密生成参数密文;
  4. 生成当前时间的时间戳;
  5. 生成一串随机字符串;
  6. 将参数密文、AES密钥密文、时间戳、随机字符串进行MD5计算 , 得到md5值;
  7. 使用APP自己的RSA私钥对md5值签名 , 得到签名值;
  8. 最后将参数密文、AES密钥密文、时间戳、随机字符串、签名值一起发送到服务端;
 
再来讲一下服务端收到请求后的解密流程:
  1. 对比请求参数中时间戳与服务器端获取的当前时间戳 , 判断两者差值是否在一定的时间之内 , 超过则认为请求过期;
  2. 从系统缓存中查找参数中随机字符串是否已存在 , 如果已存在则认为是一次重复请求 , 不存在则将该随机字符串放入缓存;
  3. 将参数密文、AES密钥密文、时间戳、随机字符串进行MD5计算 , 得到md5值
  4. 使用客户端上传的RSA公钥验证参数中的签名是否来自合法授权的客户端 , 防止非法客户端篡改数据;
  5. 使用自己的RSA私钥解密AES密钥密文 , 得到AES明文密钥;
  6. 使用AES明文密钥解密参数密文得到参数明文;
  7. 进行正常的业务处理流程;
  8. 返回数据加密流程与客户端加密流程一致;
总结要保证APP与API通信安全 , 首先要使用HTTPS协议 , 同时前后端还需要使用AES+RSA混合加密的方式来对数据进行加密 , 另外为了防止重放攻击、中间人攻击 , 还需要在数据加密的基础上加入时间戳、随机字符串以及数字签名等校验手段进一步提高通信的安全性 。


推荐阅读