相关数据的认证加密 AEAD

Socks5 流量转发

Socks5 是一个即为广泛使用的流量转发协议,它可以将用户本身的 TCP 流量(或 UDP),进行一层包裹。将其先发送到某个中转服务器,而后转发至原本的目标服务器。采用这种形式,可以实现跳板访问,从而访问原本不允许直接访问的资源。
如,公网开放一台跳板机作为与内部网络联通的中转点,在自己家就可以通过这个跳板机访问原本不允许访问的内部网络。

Socks5 本身并未对内容进行加密,因此在某种特殊的需求下,需要对实际的 TCP 流量(往往是 HTTP、HTTPS 流量)进行加密,以避免被审查机构发现。这也是最基础的代理工具的实现——在 Socks5 的基础上,增加一层加密(最早的 SS 就是类似的形式)。

以早期的 SS 为例,其使用的是流加密,在 Socks5 协议前增加了一个初始 IV。通过 IV 和用户密码作为流加密的密钥,原则上来说,这样已经可以保证数据的安全性,第三方很难去获取传输的数据明文。但在某些特殊情况下,可以借助这种模式来定位这个服务器是否是 SS 服务器。

主动探测技术

在 SS 中,除去 IV 部分的第一个字节,按照 Socks5 的格式记录了目的地址的格式:

  • 01: IPv4
  • 03: 域名
  • 04: IPv6

由于使用了流加密,因此这部分会有 28=2562^8=256 种可能,如果尝试这 256256 种可能,那么其中应该应该只有 33 种是合法的,只有 11 种是可以正确被响应处理的。因此,根据服务器断开请求、发起者得到相应的次数,既可以反向推断 服务器是否是一个 SS 服务器

一次性验证

上述主动探测能够实现的原因是 第三方可以假装用户任意地修改数据包。如果服务端发现数据包被修改,直接返回错误信息,那么只有原本的流量可以被正确响应,这样就和其他任意的未知加密协议没有区别了。第三方无法判断是否为 SS 服务器。

要避免第三方修改传输的数据内容,就是要对数据进行 完整性 保护。使用哈希算法给数据做一个摘要,比对摘要是否相同。在实际使用中,为了避免第三方生成摘要,使用 HMAC 来计算摘要值。

原本的 Socks5 协议,在握手建立完毕后,传输的流量就是实际的流量,因此不需要在 Socks5 协议中对数据长度进行处理。由于流密码的特性,原本的 SS 也不需要考虑长度。但在增加 HMAC 后,需要计算要对哪部分数据进行摘要计算,因此需要增加一个长度字段。

那么新的问题来了,如果第三方将这个字段设置成一个很大的值,而后面的数据并不改动,如果发现服务器会等待很久才会关闭连接,那么就可以说明这是一个 SS 服务器。
由于这种行为符合还有需要读取的字段未被读入,而第三方只修改了一个字段,那么也即这个字段必定是长度字段。在这个特定位置是长度字段的协议是很少的,因此完全可以认为其是 SS 服务器(当然,实际中也可以在综合别的方式交叉验证,但是起码可以列为重点关注名单)

AEAD

上述主动探测的原因是 数据包仍然有未被完整性保护的部分。造成这个的原因可以理解为是用于数据完整性保护的部分未被保护(长度字段也应该算入实现完整性保护的部分)。

到这里,就需要涉及到密码学与数据传输的极为重要两部分: 加密算法(
Encryption Algorithm) 和 消息认证(Message Authentication Code, MAC)。

如果不加以深度考虑,那么有如下三种形式:

  • Enctypt-and-MAC(E&M): 先加密而后校验
  • Encrypt-then-MAC(EtM): 加密校验再加密
  • MAC-then-Encrypt(MtE): 先校验再加密

可以看出,前两种未被 MAC 部分进行加密保护,在类似上面提到的情况是,可能会造成安全隐患。
而第三者则是前面提到的一次性验证,在使用流密码进行加密的时候,仍然会由于设计问题导致安全隐患(流密码加密后,对应的字节位置不会被修改)

为了解决上述的问题,新的将加密和验证融为一体的算法被提出,这类被称为带 相关数据的认证加密(Authenticated Encryption with Associated Data, AEAD)。

参考资料