Shadowsocks 文档
旅游导航
AEAD
AEAD 代表带有关联数据的认证加密。 AEAD 密码同时提供机密性、完整性和真实性。 它们在现代硬件上具有出色的性能和能效。 用户应尽可能使用 AEAD 密码。
建议使用以下 AEAD 密码。 兼容的 Shadowsocks 实现必须支持 AEAD_CHACHA20_POLY1305。 具有硬件 AES 加速的设备的实现也应该实现 AEAD_AES_128_GCM 和 AEAD_AES_256_GCM。
名字 | 别名 | 按键大小 | 盐量 | 随机数大小 | 标签大小 |
AEAD_CHACHA20_POLY1305 | chacha20-ietf-poly1305 | 32 | 32 | 12 | 16 |
AEAD_AES_256_GCM | aes-256-gcm | 32 | 32 | 12 | 16 |
AEAD_AES_128_GCM | aes-128-gcm | 16 | 16 | 12 | 16 |
请参阅 IANA AEAD 注册表 用于命名方案和规范。
密钥派生
主密钥可以直接从用户输入或从密码生成。
HKDF_SHA1 是一个函数,它接受一个秘密密钥、一个非秘密盐、一个信息字符串,并生成一个密码强度很高的子密钥,即使输入的秘密密钥很弱也是如此。
HKDF_SHA1(key, salt, info) => 子键
信息字符串将生成的子项绑定到特定的应用程序上下文。 在我们的例子中,它必须是不带引号的字符串“ss-subkey”。
我们使用 HKDF_SHA1 从预共享主密钥派生每个会话子密钥。 在预共享主密钥的整个生命周期中,Salt 必须是唯一的。
认证加密/解密
AE_encrypt 是一个函数,它接受一个秘密密钥、一个非秘密随机数、一条消息,并生成密文和一个身份验证标签。 对于每次调用中的给定密钥,Nonce 必须是唯一的。
AE_encrypt(key, nonce, message) => (密文, 标签)
AE_decrypt 是一个函数,它采用密钥、非秘密随机数、密文、身份验证标签,并生成原始消息。 如果任何输入被篡改,解密将失败。
AE_decrypt(key, nonce, ciphertext, tag) => 消息
TCP
AEAD 加密的 TCP 流以随机生成的盐开始,以派生每个会话的子密钥,然后是任意数量的加密块。 每个块具有以下结构:
[加密负载长度][长度标签][加密负载][负载标签]
有效载荷长度是一个 2 字节的大端无符号整数,上限为 0x3FFF。 高两位保留,必须设置为零。 因此,有效负载限制为 16*1024 – 1 个字节。
第一个 AEAD 加密/解密操作使用从 0 开始的计数随机数。在每次加密/解密操作之后,随机数都会递增 XNUMX,就好像它是一个无符号小端整数一样。 请注意,每个 TCP 块涉及两个 AEAD 加密/解密操作:一个用于有效负载长度,一个用于有效负载。 因此,每个块将 nonce 增加两次。
TCP
AEAD 加密的 TCP 流以随机生成的盐开始,以派生每个会话的子密钥,然后是任意数量的加密块。 每个块具有以下结构:
[加密负载长度][长度标签][加密负载][负载标签]
有效载荷长度是一个 2 字节的大端无符号整数,上限为 0x3FFF。 高两位保留,必须设置为零。 因此,有效负载限制为 16*1024 – 1 个字节。
第一个 AEAD 加密/解密操作使用从 0 开始的计数随机数。在每次加密/解密操作之后,随机数都会递增 XNUMX,就好像它是一个无符号小端整数一样。 请注意,每个 TCP 块涉及两个 AEAD 加密/解密操作:一个用于有效负载长度,一个用于有效负载。 因此,每个块将 nonce 增加两次。