本文档概述了 Shadowsocks Windows 客户端中使用的加密系统。它涵盖了加密框架、支持的加密方法以及在代理操作期间数据如何加密和解密。有关系统代理配置的详细信息,请参阅系统代理配置。
Shadowsocks 依赖加密来保护客户端和服务器之间的流量。加密系统由一个模块化框架组成,支持多种加密算法,包括流密码和带关联数据的认证加密(AEAD)密码。该系统设计为可扩展的,允许轻松添加新的加密方法。
加密实现基于通过 P/Invoke 访问的本机加密库构建,并通过抽象层来为应用程序的其余部分维护一个清晰的接口。
来源: shadowsocks-csharp/Encryption/EncryptorFactory.cs1-88 shadowsocks-csharp/Encryption/IEncryptor.cs1-15
加密系统采用分层架构,具有通用接口和工厂模式用于实例化。IEncryptor 接口定义了所有加密实现必须遵循的契约。EncryptorBase 抽象类提供了通用功能,而具体的实现则处理不同的加密算法。
来源: shadowsocks-csharp/Encryption/IEncryptor.cs1-15 shadowsocks-csharp/Encryption/EncryptorBase.cs1-97 shadowsocks-csharp/Encryption/EncryptorFactory.cs1-88
Shadowsocks 使用本机加密库来高效实现加密。这些库通过 .NET 的 P/Invoke 访问。
主要的本机库是 libsscrypto.dll,它为 AEAD 和流密码提供加密操作。该库在运行时动态加载,并通过处理 P/Invoke 调用的包装类进行访问。
来源: shadowsocks-csharp/Encryption/Sodium.cs1-113 shadowsocks-csharp/Encryption/MbedTLS.cs1-109
EncryptorFactory 负责根据指定的方法和密码创建相应的加密器实例。它维护一个支持的加密方法及其对应实现类的注册表。
在静态初始化期间,工厂会注册来自不同提供程序的所有可用加密方法:
当多个实现支持相同的密码时,工厂会优先选择更安全的实现。例如,如果 libsodium 和 MbedTLS 都支持 AES-256-GCM,则工厂在可用时将优先选择 libsodium 实现。
来源: shadowsocks-csharp/Encryption/EncryptorFactory.cs10-87
Shadowsocks Windows 客户端支持多种加密方法,分为两大类:
AEAD(带关联数据的认证加密)密码提供机密性和认证性。它们通常比流密码更安全。
| 密码 | 密钥大小(字节) | 盐值大小(字节) | 随机数大小(字节) | 标签大小(字节) |
|---|---|---|---|---|
| aes-128-gcm | 16 | 16 | 12 | 16 |
| aes-192-gcm | 24 | 24 | 12 | 16 |
| aes-256-gcm | 32 | 32 | 12 | 16 |
| chacha20-ietf-poly1305 | 32 | 32 | 12 | 16 |
| xchacha20-ietf-poly1305 | 32 | 32 | 24 | 16 |
流密码一次加密一个字节的数据。虽然通常速度更快,但它们不提供认证。
| 密码 | 密钥大小(字节) | IV 大小(字节) |
|---|---|---|
| aes-128-ctr | 16 | 16 |
| aes-192-ctr | 24 | 16 |
| aes-256-ctr | 32 | 16 |
| aes-128-cfb | 16 | 16 |
| aes-192-cfb | 24 | 16 |
| aes-256-cfb | 32 | 16 |
| camellia-128-cfb | 16 | 16 |
| camellia-192-cfb | 24 | 16 |
| camellia-256-cfb | 32 | 16 |
| chacha20-ietf | 32 | 12 |
| rc4-md5 | 16 | 16 |
| salsa20 | 32 | 8 |
来源: shadowsocks-csharp/Encryption/EncryptorBase.cs3-59 shadowsocks-csharp/Encryption/EncryptorFactory.cs18-54
数据在加密系统中以下列方式流动:
来源: shadowsocks-csharp/Encryption/IEncryptor.cs5-13 shadowsocks-csharp/Encryption/EncryptorFactory.cs57-71
AEAD 密码提供认证加密,这意味着它们可以检测加密消息是否被篡改。Shadowsocks 根据 SIP004 规范实现 AEAD 密码。
AEAD 加密过程遵循以下步骤:
对于 UDP 数据包,使用更简单的过程,因为每个数据包都是独立处理的。
来源: shadowsocks-csharp/Encryption/Sodium.cs66-95 shadowsocks-csharp/Encryption/MbedTLS.cs86-106
流密码将数据加密为连续的字节流。该过程包括:
流密码通常比 AEAD 密码快,但由于不认证加密数据,因此安全性较低。
来源: shadowsocks-csharp/Encryption/Sodium.cs97-111 shadowsocks-csharp/Encryption/MbedTLS.cs58-81
在进行任何加密操作之前,必须初始化本机加密库。这会在应用程序启动时自动发生。
Sodium 类将嵌入的 libsscrypto.dll 解压到临时位置并进行初始化。在初始化期间,它还会检查硬件加速 AES-256-GCM 支持的可用性,这会影响首选哪种实现。
来源: shadowsocks-csharp/Encryption/Sodium.cs14-55 shadowsocks-csharp/Encryption/MbedTLS.cs14-35
Shadowsocks Windows 客户端的加密系统在保证性能的同时优先考虑安全性:
建议使用诸如 aes-256-gcm 或 chacha20-ietf-poly1305 等 AEAD 密码,以获得安全性和性能的最佳平衡。
来源: shadowsocks-csharp/Encryption/EncryptorFactory.cs18-30 shadowsocks-csharp/Encryption/Sodium.cs22-51
加密系统与 Shadowsocks Windows 客户端的其他组件集成
加密系统主要由 TCPRelay 和 UDPRelay 组件用于加密和解密客户端与服务器之间的流量。ShadowsocksController 协调这些组件的配置和初始化。
来源: shadowsocks-csharp/Encryption/IEncryptor.cs5-13 shadowsocks-csharp/Encryption/EncryptorFactory.cs57-71