菜单

加密框架

相关源文件

目的与范围

加密框架是 Shadowsocks Windows 中处理所有加密操作的核心子系统。它为不同的加密算法提供统一的接口,实现客户端和服务器之间的安全通信。本页面介绍加密系统的架构,包括构成该框架的接口、基类和工厂。

有关特定加密库及其实现的详细信息,请参阅加密库

框架架构

加密框架遵循模块化设计模式,职责分离明确。它包含三个主要组件:

  1. 接口 (IEncryptor) - 定义所有加密实现必须遵循的契约
  2. 基类 (EncryptorBase) - 为加密实现提供通用功能和常量
  3. 工厂 (EncryptorFactory) - 根据请求的方法创建相应的加密器实例

来源: shadowsocks-csharp/Encryption/IEncryptor.cs5-14 shadowsocks-csharp/Encryption/EncryptorBase.cs61-96 shadowsocks-csharp/Encryption/EncryptorFactory.cs10-87

IEncryptor 接口

IEncryptor 接口定义了所有加密实现所需的核心功能。它扩展了 IDisposable 以确保正确的资源清理。

来源: shadowsocks-csharp/Encryption/IEncryptor.cs5-14

接口方法

  • Encrypt/Decrypt:加密/解密 TCP 数据
  • EncryptUDP/DecryptUDP:加密/解密 UDP 数据
  • AddrBufLength:用于跟踪处理过程中地址缓冲区长度的属性

EncryptorBase 抽象类

EncryptorBase 抽象类实现了 IEncryptor 接口,并为所有加密实现提供通用功能。它还定义了在整个加密过程中使用的常量和元数据结构。

EncryptorBase 的主要方面

  • 定义缓冲区大小和地址类型的常量
  • 存储加密方法和密码
  • 声明具体实现必须提供的抽象方法
  • 包含嵌套的 EncryptorInfo 类,该类保存有关加密方法的元数据

EncryptorInfo 类存储流密码和 AEAD 密码的重要元数据:

属性描述
KeySize加密密钥的字节大小
IvSize初始化向量(用于流密码)的大小
SaltSize盐值(用于 AEAD 密码)的大小
NonceSizeNonce 值(用于 AEAD 密码)的大小
TagSize认证标签(用于 AEAD 密码)的大小
类型密码的类型标识符
InnerLibName加密库使用的内部名称

来源: shadowsocks-csharp/Encryption/EncryptorBase.cs3-96

EncryptorFactory

EncryptorFactory 是负责根据请求的加密方法创建相应加密器实例的核心组件。它使用工厂模式在运行时实例化正确的实现。

来源: shadowsocks-csharp/Encryption/EncryptorFactory.cs10-87

注册过程

EncryptorFactory 维护一个静态字典 (_registeredEncryptors),该字典将加密方法名称映射到其实现类。此注册发生在静态构造函数中:

  1. 从每个实现(AEADOpenSSL、AEADSodium、AEADMbedTLS、Plain)中检索支持的密码
  2. 检查功能可用性(如 libsodium 中的 AES-256-GCM)
  3. 在字典中注册每个方法及其实现类

注册遵循优先顺序,确保为每个方法使用最优化的实现。

来源: shadowsocks-csharp/Encryption/EncryptorFactory.cs16-55

实例创建

当调用 GetEncryptor 并带上方法和密码时:

  1. 如果方法为 null/空,则默认为服务器的默认方法
  2. 方法名转换为小写
  3. 在注册表中查找实现类
  4. 使用反射创建新实例,并传递方法和密码

来源: shadowsocks-csharp/Encryption/EncryptorFactory.cs57-71

支持的加密类型

加密框架支持两种主要的加密类型:

  1. 流密码 (Stream Ciphers) - 将数据作为连续流处理的传统加密方法
  2. AEAD 密码 (AEAD Ciphers) - 提供机密性和完整性的现代认证加密方法

流密码

流密码在 Shadowsocks.Encryption.Stream 命名空间中实现。这包括更简单的加密方法,例如:

  • plain - 不加密(仅用于测试)
  • 各种旧的密码方法(详情请参阅加密库

AEAD 密码

AEAD(带关联数据的认证加密)密码在 Shadowsocks.Encryption.AEAD 命名空间中实现。这些提供更高的安全性,建议用于大多数用例。实现分为三个类:

  1. AEADOpenSSLEncryptor - 使用 OpenSSL 实现 AEAD 密码
  2. AEADSodiumEncryptor - 使用 libsodium 实现 AEAD 密码
  3. AEADMbedTLSEncryptor - 使用 mbed TLS 实现 AEAD 密码

工厂根据可用性和性能考量来优先选择实现。例如,如果 libsodium 的 AES-256-GCM 实现可用,它将优先于 mbed TLS 实现。

来源: shadowsocks-csharp/Encryption/EncryptorFactory.cs18-30

在应用程序中的使用

加密框架主要由代理服务(TCPRelay 和 UDPRelay)使用,用于在向远程服务器发送数据之前或从远程服务器接收数据之后对其进行加密/解密。

典型流程:

  1. ShadowsocksControllerEncryptorFactory 获取一个加密器实例
  2. 加密器被传递给代理服务
  3. 收到数据时,使用加密器解密
  4. 发送数据时,使用加密器加密

这种抽象允许应用程序轻松切换不同的加密方法,而无需更改代理服务代码。

调试和监控

EncryptorFactory 包含一个实用方法 DumpRegisteredEncryptor(),它返回所有已注册加密方法及其实现类的字符串表示。这对于调试和日志记录很有用。

来源: shadowsocks-csharp/Encryption/EncryptorFactory.cs73-86

总结

加密框架为 Shadowsocks Windows 客户端提供了一个灵活、可扩展的数据加密和解密系统。通过使用工厂模式,它将实现细节从应用程序的其余部分中抽象出来,从而可以轻松添加新的加密方法或改进现有方法,而不会影响其他组件。

该框架在有多个选项可用时优先选择更安全、更高效的实现,并为所有加密操作提供一致的接口,无论是 TCP 还是 UDP 流量。