V2Ray 的认证和加密方式简介

2015/10/03
V2Ray 默认使用自有的 VMess 协议。目前协议已趋于稳定,1.0 版本发布前,如没有重大缺陷,将不会再改。
VMess 协议包含两种数据格式,分别针对 TCP 和 UDP 的数据特点而设计。其中 TCP 的数据包在请求数据中加入了约 80 字节的头部,响应数据加入了 4 字节的头部;而 UDP 数据包则统一加入了约 40 字节的头部。TCP 的非对称设计主要是因为多数 TCP 数据包是 HTTP 通讯,而 HTTP 通讯的请求数据大小通常远小于响应数据,于是在请求数据中多加入一些额外的信息,不会对性能产生太大的影响。

认证方式

VMess 强制要求用户 ID 为一个 16 字节长的随机值,可由机器随机生成。在 VMess 的 TCP 请求数据包和 UDP 数据包中,起始的 16 字节均为认证信息。这个认证信息基于(用户 ID + 时间)生成,每一个认证信息在 1 分钟内有效(时间可以调节),类似当下流行的两步验证的验证码。在实际应用中,V2Ray 会在当前时间的前后 30 秒内随机选择一个时间点,用于生成认证信息,这样使得每一个数据包的头部都不相同。
这样做的好处是:
  • 一定程度上抵御流量重放攻击,攻击者必须不间断地截获有效的认证信息;
  • 高效的身份验证,服务器端不需要解密数据即可判断用户的有效性,可以抵御更高流量的 DoS 攻击;
坏处是:
  • 要求客户端和服务器的时间同步(误差在一分钟内),尽管有很多原因能导致机器时间不准,但我不认为这将会是一个严重的问题;

加密方式

VMess 主要使用两种加密/散列方式:AES-128-CFB 和 HMAC(MD5),在这两种方式被证明有缺陷之前,将不会引入更加复杂的加密方式。对于移动设备/路由器等计算资源薄弱的设备,将来会考虑引入轻量级的加密方式(如 chacha20)。目前高端的 CPU (Intel i5/i7,ARMv8-A 等)都已支持 AES-NI轻量级加密方式的必要性还有待研究。
TCP 和 UDP 数据的认证信息使用 HMAC(MD5) 散列,不可被逆转。
TCP 请求的指令部分使用固定的 Key 和随机 IV 加密,数据部分使用随机 Key 和随机 IV 加密,TCP 响应也使用随机 Key 和随机 IV 加密;UDP 数据均采用固定的 Key 和随机 IV 加密。
具体的实现细节请参考 VMess 协议

数据包特征

基于散列和 IV 带来的随机性,VMess 数据包的内容可以被认为是完全随机的。至于数据包的长度,V2Ray 会把 VMess 的头部和客户端发来的首个数据包合并为一个数据包,以减小数据包的可识别性,实际效果还在研究中

Related Posts