微信开发者

如何防止攻击者窃听你的“秘密”

在互联网应用服务开发过程中,我们对网络请求的发起者称为客户端,而请求的目标服务则称为服务端,每个请求都会有客户端和服务端的角色对应。
除了小程序、WEB / H5 网页、原生 APP 这些常见的客户端外,大部分开发者的后端服务也在扮演客户端角色。比如:
  1. 开发者后端服务调用微信平台 sns/jscode2session 接口,用于换取小程序用户登录信息。
  2. 开发者后端服务调用微信平台 wxa/getwxacode 接口,用于获取微信小程序码、
  3. 小程序开发服务商调用微信开放平台 fastregisterweapp 接口,为商家快速注册小程序。
  4. ......
在这些向微信平台通信的情景下,你的后端服务实际上在扮演「客户端」角色,微信平台是「服务端」角色。
现代互联网中,大部分客户端和服务端间的交互,都是通过如 RESTful 或 GraphQL 等 API 接口完成。

微信小程序在一开始,就为了 API 接口的安全做了很多规范性限制和建议,这里举一些代表性例子:
  1. 小程序的服务器域名必须支持 HTTPS 协议,且境内小程序的服务器域名需进行互联网备案。
  2. 业务操作权限应在后端服务中确定,不应该放在 API 参数中直接传递。
  3. 对每一次调用进行权限校验,确认操作者信息,防止发生越权行为。
  4. 不要相信客户端提交的数据,在业务处理前一定要做必要的参数校验。
  5. ......
在前后端开发联调过程中,开发者通常会使用代理软件对自己开发的项目服务做请求转发,便于切换开发环境和进行测试。
代理软件可以在 客户端 与 真实服务器 之间进行数据传输。这时,代理软件可以解密并查看通过 SSL 加密的数据,然后再重新加密数据发送给原始目的地。对于客户端和服务器来说,TA 们仍然认为自己处于一个安全的加密连接中,实际上数据的安全性已被破坏。

Image

除了监听之外,由于代理软件可以解密 SSL 加密的通信,因此也支持修改传输中的数据,甚至插入恶意内容。

Image

上述这种中间人代理,也会被不法分子恶意使用,用于任意监听自己设备中的所有请求。TA 们会在自己的设备中运行其他开发者开发的「小程序」、「WEB 网页」 或「原生APP」,然后通过中间代理获取和篡改正常请求的「请求包」和「响应包」,并有针对的对目标请求进行重放,用于实现恶意的目的(比如刷经验、修改游戏结果、创建 1 分钱订单等)。

为了防止中间人代理攻击,我们就需要在 SSL 加密的基础上,对请求包和响应包的明文再进行一次加密,这种方法可以提供额外的安全层次,保障数据即使在被代理软件解密后仍保持安全。

首先,根据自身业务情况,寻找合适的加密方式:

  • 非对称加密:客户端和服务器维护两组公私加密密钥,每次接口请求时,先对明文数据进行加密,另一方收到密文后用对应的反向密钥解密。常见的非对称加密有 RSA、DSA、ECC,非对称加密安全性高,但加解密速度慢,不太适合请求体或响应体太大的情况。
  • 对称加密:客户端和服务端维护一组密钥,每次接口请求时,对明文数据进行加密,另一方收到时用同样的密钥解密。常见的对称加密有 DES、3DES、IDEA、RC5、RC6、Blowfish,对称加密加解密速度快,适合对大数据做加解密处理,安全性有所下降。
  • 整合方案:请求时,客户端对明文用对称加密方式加密,对称密钥随机生成,然后用非对称加密方式加密前面的对称密钥,最后将密文和加密后的对称密钥内容合并发出;服务端收到时,按照反向流程进行解密,响应包也是相同的处理流程。
接下来,在客户端和服务端进行安全的密钥交换,如 Diffie-Hellman 密钥交换算法、公钥基础设施(PKI)
最后,使用不同的加密方式对请求体数据进行数字签名,验证数据在传输过程中是否被篡改,如被篡改则直接丢弃数据。
上面的策略中,实现成本最高的就是密钥交换,安全的密钥交换需要一个 可信赖的第三者 对「客户端」和「服务端」双方都进行身份验证。

微信小程序为开发者提供了 小程序加密网络通道 和 API 安全鉴权 来帮助开发者完成对请求的二次加密

小程序加密网络通道

微信平台维护了一个用户维度的可靠 Key,用于小程序和后台通信时进行加密和签名。开发者可以分别通过小程序前端 API 和微信后台提供的服务端接口,获取到用户加密 key。
  1. 小程序端端通过 wx.getUserCryptoManager().getLatestUserKey 获取加密密钥信息
  2. 发起 wx.request 请求时使用第一步得到的加密密钥信息对参数进行加密(加密方法可以自定义)
  3. 服务端请求服务端接口 wxa/business/getuserencryptkey 拿到 encryptKey 用于解密

Image

更多请参考🔗官方文档

API 安全鉴权

在「开发者后端服务」和「微信平台」通信场景下,微信小程序也推出了 API 安全鉴权模式。
  1. 在「微信小程序开发后台」和「开发者后端服务」中分别配置加密密钥。
  2. 发送微信 api 请求时,「开发者后端服务」使用对应的密钥和加密方式对请求体进行加密
  3. 「微信开放平台」收到请求后,使用配置的加密密钥进行解密,处理后再通过密钥加密。
  4. 「开发者后端服务」收到请求响应后,使用加密密钥进行解密,获得明文。
更多请参考🔗官方文档

更多可能?

除了上面两个方案,微信小程序团队还做了些什么?
由于大部分的代理攻击都发生在「用户客户端」到「开发者服务端」之间,而不少基础阶段的开发者对「小程序加密网络通道」难以掌握使用。
秉承着简单、好用的理念,能否有一种方式可以做到:无需开发者投入太多精力,就能够在通信时全程加密。
微信团队结合多年安全防护经验积累,推出「微信网关」,具备系统化、多层级的安全防护能力。开发者接入后,就会将「小程序」到「开发者服务端」的通信链路自动从公网链路切换到微信专线链路,并且全程对请求内容进行二层加密,有效防止中间人代理攻击。

Image

「微信网关」支持微信小程序自助一键接入方式,你无需任何代码改动和版本发布即可体验,快来试试看!🔗体验链接