立即停止使用RSA
在Trail of Bits,我们评审过大量代码。从主流开源项目到激动人心的新专有软件,我们见识过所有类型。但这些系统有一个共同点:出于某种难以解释的原因,人们似乎仍然认为RSA是值得使用的优秀密码系统。请允许我节省您的时间和金钱并直言不讳——如果您向我们提交使用RSA的代码库,您将需要支付我们解释为何应该停止使用它所需的时间费用。
RSA的本质脆弱性
RSA是一种内在脆弱的密码系统,包含无数普通软件工程师难以避免的隐患。弱参数难以(甚至不可能)检测,其性能低下迫使开发人员采取风险捷径。更糟糕的是,在填充预言机攻击被发现20年后,这类攻击仍然猖獗。虽然理论上可能正确实现RSA,但数十年的毁灭性攻击证明,这种壮举在实践中可能无法实现。
重温RSA原理
RSA是一种公钥密码系统,有两个主要用例:公钥加密(允许用户Alice发布公钥供他人发送加密消息)和数字签名(允许Alice"签名"消息以供验证)。RSA的便利之处在于签名算法基本上就是加密算法的逆运算。
参数设置需要选择两个素数p和q生成模数N=pq,然后选择满足ed ≡ 1 mod (p-1)(q-1)的公钥指数e和私钥指数d。加密时计算C ≡ Mᵉ (mod N),解密时计算M ≡ Cᵈ (mod N)。
参数选择的陷阱
素数选择
RSA安全性基于大数分解难题,但素数选择方式存在多种风险:
- 素数重复使用:如果p或q在其他RSA模数中重用,可通过GCD算法轻松分解
- 非独立选择:当p和q共享约一半高位时,可采用费马方法分解
- 特殊形式素数:如ROCA漏洞中,使用特定形式的素数导致智能卡和YubiKey易受攻击
私钥指数
小私钥指数d(小于N的四次方根)可能导致密钥恢复。虽然标准流程使用固定公钥指数避免此问题,但自定义实现中开发者常反向选择参数。
公钥指数
小公钥指数(如e=3)带来多重风险:
- Franklin-Reiter攻击:可解密具有已知固定距离的相关消息
- 密钥恢复:当公钥指数较小时,知晓密钥部分位的攻击者可恢复剩余位
- 签名伪造:Bleichenbacher攻击允许在Firefox和Chrome等实现中伪造任意签名
填充预言机攻击的普遍性
PKCS #1 v1.5填充方案容易受到填充预言机攻击。攻击者利用无效填充错误信息,通过数百万次密文操作逐步解密目标消息。尽管原始攻击于1998年发现,但ROBOT等现代变体仍影响Facebook和PayPal等系统。
虽然有安全证明严格的OAEP填充方案,但实现困难且可能受到Manger攻击等新型填充预言机攻击。
替代方案推荐
椭圆曲线密码学(ECC)优势:
- 参数选择公开进行,开发者只需生成随机字节作为密钥和随机数
- 基于Diffie-Hellman的方案无需填充,完全避免填充预言机攻击
具体建议:
使用Curve25519进行密钥交换和数字签名,结合ECIES协议进行加密。Curve25519专门设计避免其他曲线的缺陷,性能优异,且通过libsodium库提供多语言支持。
结论:彻底弃用RSA
RSA作为安全通信发展的重要里程碑,过去二十年的密码学研究已使其过时。椭圆曲线算法自2005年标准化以来,已集成到libsodium等直观且防误用的库中。RSA的持续广泛使用既反映了密码学家未能充分阐明其固有风险,也体现了开发者高估了自身部署能力。
安全社区需要将此视为群体免疫问题——虽然有些人可能成功部署RSA,但这向开发者发出了错误信号。我们必须一致认为在2019年使用RSA是完全不可接受的,毫无例外。
原文发表于Trail of Bits博客,2019年7月8日