Salsa20 加密
支持扩展 nonce 变体的高速流密码
客户端安全
Salsa20 是 ARX 流密码(加法-旋转-异或),无查找表,天然恒定时间,免疫缓存时序攻击。核心安全要求:同一密钥下 nonce 绝不能复用。使用 XSalsa20(192 位 nonce)启用安全随机 nonce 生成。截至 2025 年 Salsa20/20 无全轮攻击。
初始块计数器值(加密通常为 0,解密使用相同值)
关于 Salsa20
Salsa20 是 Daniel J. Bernstein 设计的 ARX 流密码,于 2005 年提交 eSTREAM 竞赛。它在 4×4 个 32 位字矩阵(总计 512 位状态)上运算,仅使用加法(mod 2³²)、位旋转和 XOR——没有 S 盒,没有查找表。这种 ARX 结构使执行时间与密钥或数据值无关,天然抵抗缓存时序侧信道攻击。64 位流计数器允许在不处理先前块的情况下随机访问密钥流中的任意位置。
Salsa20 在经过严格的多年评估后于 2008 年入选 eSTREAM Profile 1(软件)。Bernstein 于 2011 年定义了 XSalsa20:使用 HSalsa20 函数从 192 位 nonce 的前 128 位和原始密钥推导 256 位子密钥,将派生子密钥和剩余 64 位 nonce 输入 Salsa20/20。这种构造支持随机生成 192 位 nonce 而不受生日界限制,使 XSalsa20 成为 NaCl secretbox(XSalsa20-Poly1305 AEAD)的基础。
算法对比
| 算法 | 轮数 | Nonce 长度 | 速度 | 最佳用途 |
|---|---|---|---|---|
| Salsa20/20 | 20 | 64 bits (8 bytes) | 标准 | 严格管理顺序 nonce 的长期会话加密;高吞吐量数据加密;安全分析和 eSTREAM 认证部署 |
| Salsa20/12 | 12 | 64 bits (8 bytes) | 快速 | 全 20 轮余裕超过需求的高性能加密场景;Bernstein 推荐的性能-安全权衡;eSTREAM 组合配置文件软件推荐 |
| Salsa20/8 | 8 | 64 bits (8 bytes) | 最快 | 流密码实现基准测试;密码学研究和性能测量;不用于安全关键数据加密 |
| XSalsa20 | 20 | 192 bits (24 bytes) | 标准 | 随机生成 nonce 或无法管理 nonce 唯一性的应用;NaCl/libsodium secretbox 兼容性;无法同步独立 nonce 计数器的多方密钥共享 |
Salsa20 工作原理
Salsa20 初始化 4×4 个 32 位字矩阵:编码 ASCII 字符串 “expand 32-byte k” 的四个常量字 (0x61707865, 0x3320646e, 0x79622d32, 0x6b206574)、来自 256 位密钥的八个 32 位字、来自 64 位流计数器(位置 0)的两个 32 位字,以及来自 64 位 nonce 的两个 32 位字。
核心轮函数是对 (a,b,c,d) 的季度轮:b⊕=(a+d)⋘7; c⊕=(b+a)⋘9; d⊕=(c+b)⋘13; a⊕=(d+c)⋘18。双轮先应用列轮(对 4×4 矩阵每列进行季度轮),再应用对角轮(对每条对角线进行季度轮)。Salsa20/20 应用 10 个双轮(共 20 轮)。最终输出块 = 20 轮变换后的状态与原始输入状态的 XOR(而不仅仅是轮次结果)。
64 位流计数器每个 64 字节密钥流块增加 1,每个(密钥,nonce)对提供总计 2⁷⁴ 字节密钥流。流密码输出与明文 XOR:加密和解密中相同位置使用相同密钥流字节。基于计数器的构造支持通过设置计数器值跳转到任意密钥流位置,允许并行加密独立的 64 字节段。
轮数变体
- Salsa20/20(20 轮,标准):完整变体;10 个列-对角线双轮,最大安全余裕;eSTREAM 提名;无已知全轮攻击(最佳已发表攻击:Crowley 2005 降至理论);推荐用于所有安全关键应用。
- Salsa20/12(12 轮):精简轮变体,6 个双轮;Bernstein 推荐的性能-安全平衡点;比 Salsa20/20 快约 35%;12 轮无已知攻击;eSTREAM 组合列表的次要推荐。
- Salsa20/8(8 轮):最快精简轮变体,4 个双轮;存在已知区分器和降低安全结果(Aumasson 等人 2008 年将 8 轮攻击复杂度降至 2²⁴⁹);不推荐用于新的安全敏感部署;仅用于基准测试或研究。
主要特性
- ARX 设计(加法-旋转-XOR):无 S 盒,无查找表;所有操作均为 32 位加法、位旋转和 XOR;执行时间与密钥或数据值无关,天然免疫缓存时序和查找表侧信道攻击。
- 通过 64 位计数器实现大密钥流:每个(密钥,nonce)对 2⁶⁴ 块 × 64 字节 = 2⁷⁴ 字节密钥流;支持通过设置计数器值随机访问任意 64 字节密钥流块,无需重新处理先前块。
- 64 位 nonce(Salsa20 基础):需要严格的应用级 nonce 唯一性;在同一密钥下 2³² 条消息后,随机 nonce 碰撞的生日界概率变得不可忽视;对长期或共享密钥使用 XSalsa20(192 位 nonce)。
- XSalsa20(192 位 nonce,Bernstein 2011):HSalsa20 从(密钥,nonce[0:128])派生 256 位子密钥,与 nonce[128:192] 一起输入 Salsa20/20;支持完全随机的 nonce 生成(无需 nonce 管理);NaCl/libsodium secretbox 标准。
- eSTREAM Profile 1(软件,2008):经独立小组多年公开评估后入选;Salsa20/12 是 eSTREAM 组合的主要软件流密码;Salsa20/20 提供最大安全余裕;无 12 或 20 轮变体被破解的已知案例。
安全注意事项
- Nonce 复用是灾难性的:用相同(密钥,nonce,计数器)加密两个明文会产生 XOR 等于明文 XOR 的密文,从而完全恢复明文。强制执行全局唯一 nonce(如基于计数器的 nonce 分配或随机 XSalsa20 nonce)。XSalsa20 的 192 位随机 nonce 即使有数十亿条消息也将碰撞概率降至可忽略。
- 短 nonce 生日界(仅 Salsa20):64 位 nonce 下,同一密钥的约 2³² 条消息后,随机 nonce 碰撞概率约为 50%。使用唯一顺序 nonce,或切换到 XSalsa20(192 位 nonce)使生日碰撞概率在任何实际消息量下都可忽略。
- 精简轮攻击:Salsa20/20 或 Salsa20/12 无已知攻击。对于 Salsa20/8(8 轮),Aumasson 等人(2008)展示了复杂度低于暴力破解的区分器攻击。若安全是需求,使用 Salsa20/20;Salsa20/8 仅用于性能基准测试。
- 无认证:Salsa20 仅提供机密性。缺少独立 MAC 的情况下密文修改不可检测。使用 XSalsa20-Poly1305(NaCl secretbox)或 ChaCha20-Poly1305(RFC 8439)进行认证加密。在需要验证密文完整性时,绝不单独使用 Salsa20(无 MAC)。
实际应用
- NaCl secretbox / libsodium crypto_secretbox_xsalsa20poly1305:XSalsa20-Poly1305 是 Daniel Bernstein NaCl 库中的原始认证对称加密原语,提供带 192 位 nonce 和 Poly1305 认证的 AEAD;仍广泛部署在基于 libsodium 的应用中。
- eSTREAM Profile 1(软件,2008):Salsa20/12 在 ECRYPT 卓越网络组织的 4 年公开竞赛(2004-2008)后入选为主要软件流密码候选;与 RC4、SNOW 3G 等候选一起评估。
- 对 ChaCha20 的影响:Bernstein 将 ChaCha20(2008)设计为 Salsa20 的变体,具有更好的每轮扩散;ChaCha20 使用不同的矩阵布局和季度轮旋转常量,与 Salsa20 相比在更少轮次中实现更好的位扩散。所有 ChaCha20 安全属性都源自 Salsa20 ARX 框架。
- 遗留密码系统:许多早期基于 libsodium 的 VPN 工具、文件加密实用程序和消息应用程序在 RFC 7539(2015)/ RFC 8439(2018)标准化 ChaCha20-Poly1305 之前使用 XSalsa20-Poly1305。这些部署继续支持 XSalsa20。