0.引入
这篇文章翻译自Dan Boneh的Twenty Years of Attacks on the RSA Cryptosystem,其中部分译文参考了二十年以来对 RSA 密码系统攻击综述 (seebug.org)(但是这个译文机翻有点重,而且公式也没有了)。希望通过这篇文章,对目前常见的RSA攻击进行一个总结以及较为深入的了解。
1.分解大整数(Factoring Large Integers)
我们将模分解称为对RSA的暴力攻击。尽管因数分解算法一直在改进,但在正确使用RSA时,目前的技术水平,还远远没有对RSA的安全性构成威胁。虽然大整数的因式分解是计算数学中最美丽的问题之一,但它不是本文的主题。
目前最快的分解算法是General Number Field Sieve(普通数域筛选法),其时间复杂度为
学长在服务器上操作下来情况是这样的:16核32线程分解400bits的n,需要4000s;分解505bits的n,需要67小时。
- 开放性问题1:给定整数n和e,满足gcd(e, phi(n))=1。定义函数
,是否存在一个多项式时间的算法A,对于给定n,可以计算n的分解同时能访问一些e的oracle 。
有学者指出,上述开放性问题,对于一个较小的e来说,答案是否定的。
下面我们将证明知道公开私钥 d 和分解 N 是等效的。 因此,对于知道 d 的任何一方隐藏 N 的因式分解是没有意义的。
- 分解n显然可以很容易计算得到d。
- 若给定d,我们有
,通过定义我们可以知道,k是 的倍数,我们知道 是偶数,同时有 ,( 是奇数)。对于 ,有 ,并且 是模n的平方根,由中国剩余定理我们知道,对于n=p*q,这样的数有4个。其中,有两个是正负一,还有两个是 ,其中 。使用后两者,我们就可以通过计算gcd(x-1, n)得到n的分解。有简单的论证表明,如果g是在 中随机取,那么序列 的其中一个是平方根且能分解n的概率至少为1/2。序列中的所有元素都可以在 的时间内有效计算。
2.两种简单攻击
2.1共模攻击
共模攻击是一种只需要知道多组公钥对,就可以推出明文的攻击,在上一篇中已经介绍,这里就不再赘述。
2.2Blinding——盲签名(攻击)
令<n,d>为私钥,<n,e>为公钥。我们想让Bob对m签名,Bob肯定会拒绝。于是我们选择一个随机数
不过由于大多数签名方案在签名之前对消息应用"单向散列"算法,这种攻击并不是一个严重的问题。况且,正如标题中攻击在括号里一样,这种盲签名在区块链中应用更广。
3.低解密指数攻击
为了减少解密时间(或签名时间),人们希望使用一个较小的d,而不是随机的d。而这种操作就会导致下面的一些攻击。
-
定理(M. Wiener):令
,且 ,如果给定公钥,我们可以有效恢复解密指数d。 -
证明:我们有等式
,于是 此时,
是 的近似值。尽管我们不知道 ,但是我们可以用n近似它。 同时,由p、q的不等关系容易得到
,于是 我们用上面的不等式代换原有的等式
由于等式
,因为 ,根据不等式原则可以知道 。于是,上面的不等式可以进一步得到 这是一个经典的逼近关系,分数
且 在约束 内非常逼近 。实际上,所有类似这样的分数都是的连分数展开的收敛。因此我们首要做的便是计算的连分数 的收敛,其中一个连分数就等于 。由于 ,所以 ,因此 是一个最简分数。这就是一个可以算出密钥d的线性时间算法。
Wiener attack后来被 Boneh and Durfee两人改进,把d的界扩大到了
- 开放性问题2:令
,如果给定满足RSA的e、d,是否可以有效的恢复d?
4.低加密指数
为了减少加密或签名验证时间,通常会使用一个小的公钥指数。e的最小可能值为3,但为防止某些攻击,一般推荐使用
4.1 Coppersmith’s Theorem
针对RSA低公钥指数最有力的攻击是基于Copper-smith的一个定理,Coppersmith定理有很多应用,这里我们只讨论其中的一些应用,具体如下。
-
定理(Coppersmith):令n为一个整数,
是d次的一元多项式,设 其中 ,在给定 之后Marvin能够有效找到所有满足 的整数,运行时间由在维数为 且 的格上运行的LLL算法所需时间决定。 该定理为有效地求模
的所有小于 的根提供了一种算法,当X越小,算法的运行时间越短。这个定理的强大之处在于它能够找到多项式的小根。当模数为素数时,就目前而言,找不到比使用Coppersmith定理更好的求根算法。
我们概述了Coppersmith定理证明背后的主要思想,我们采用由Howgrave-Graham提出的简化方法。给定多项式
-
引理:令
是d次多项式,同时令X为正整数。假设 ,如果存在 满足 ,那么 对整数成立。 -
证明:从Schwarz不等式观察到:
因为
,所以我们可以得到结论。
引理指出,如果
Coppersmith找到了解决这个问题的方法:如果
-
对于给定m,有
对任意
,则 是 的一个根。
要使用引理4,我们必须找到多项式
如何有效地找到
在我们的例子中,我们把多项式
Hermite的一个经典结论表明:任意维数为
-
Fact(LLL):若格
有一组基 ,通过LLL算法,可以得到一个向量 满足: 算法的运行时间是输入长度的四分之一
通过LLL算法,我们就可以完成Coppersmith定理的证明。为了保证LLL算法产生的向量满足引理4的界,我们需要满足:
其中
一个自然而然的问题,Coppersmith定理能否应用于二元和多元多项式。如果
- 开放性问题3:找出可以将 Coppersmith 定理推广到二元多项式的一般条件。
4.2 Hastad广播攻击
其简化版本就是国内常说的低加密指数广播攻击,直接CRT然后开三次方就可以得到明文。一般来说,需要收集k组密文,
Hastad提出了一种更强的攻击方法。为了抵御上述的攻击,发送方会做一些简单的防御。Bob在加密之前"填充"消息,而不是直接广播加密后的
假设对于每个参与者
-
定理6(Hastad):令
是两两互质的整数,并设 。设 是 个 次多项式。假设存在唯一的 满足 假设
,给定 ,我们就可以很容易恢复 。
这个定理表明,当提供了足够多的方程,我们就可以有效地求解以两两互素的整数为模的单变量方程组。令
Hastad的原始定理比上述定理更弱。与
总结这一部分,我们注意到,要正确地防御上述广播攻击,必须使用随机填充方法,而不是使用固定填充方法。
4.3 Franklin-Reiter相关消息攻击
当Bob用相同的模数发送与Alice相关的加密消息时,Franklin和Reiter发现了一种巧妙的攻击。
-
引理(FR):令
, 是RSA的公钥,且对于 ,存在一个线性多项式 满足 。于是,给定 ,我们就可以在 的时间内恢复 。 -
证明:为了保证这部分证明的一般性,我们使用任意的
来表示它(而不是局限在 )。由于 ,我们可以知道 是多项式 的一个根。同样的, 也是 的一个根。这两个多项式都有同一个线性因子 ,因此我们就可以计算 ,如果结果是线性的,那么我们就找到了 。 我们证明了当
时,GCD的结果一定是线性的。多项式因子 将 都模成一个线性因子和一个不可约二次因子(因为 ,所以 在 中只有一个根)。因为 不能整除 ,所以GCD一定是线性的。对于 的情况,GCD几乎总是线性的。然而,对于一些罕见的 和 ,有可能得到一个非线性的GCD,在这种情况下攻击会失败。 对于
情况,攻击所需时间是 的平方。因此,只有在使用小的公钥指数 时才能应用这种攻击。对于大 ,计算GCD的工作令人望而却步。为任意 设计这样的攻击是一个有趣的问题(尽管可能很困难)。特别是,上面 和 的GCD能否在 的多项式时间内找到吗?
4.4 Coppersmith短填充攻击
Franklin-Reiter的攻击可能看起来有点人为。毕竟,为什么Bob要给Alice发送相关消息的加密呢?Coppersmith加强了攻击,并证明了一个关于填充攻击的重要的结论。
一个简单的随机填充算法可能会通过将几个随机位附加到一个末端来填充一个明文
- 定理8:令
是RSA的公钥,N长为 -bits。令 ,设 是长最多为 -bits的消息。定义 ,其中 是不同的整数,且 。如果给定 和密文 ,那么就可以有效恢复 。 - 证明:定义
。我们知道,当 时,两个多项式有共同的根 。也就是说, 是结果 的根。 的次数最多为 。此外,有 ,因此 是 的一个小根,所以我们就可以通过Coppersmith定理计算它。一旦 求出来,Franklin-Reiter攻击就可以用来计算 ,最终算出 。
当 e = 3 时,只要填充长度小于消息长度的 1/9,就可以发起攻击。 这是一个重要的结论。 但是需要注意,对于 e = 65537 这一推荐值,对于标准的模数大小来说,这种攻击就无效了。
4.5 部分密钥泄露攻击
设
- 定理9(BDF):令
是RSA的私钥,其中 有n比特。当给定 个最低有效位,Marvin可以在 的线性时间内恢复所有d。 - 定理10(Coppersmith):令
是n比特的RSA模数,给定 的 个最低有效位或 的 个最高有效位,我们就可以有效分解 。
定理9很容易从定理10推出来,事实上,对于
由于
由于我们知道
定理9被称为部分密钥泄露攻击,对于更大
为了总结这一节,我们将证明当加密指数
然后
因此
5. 执行攻击
我们将注意力转向完全不同的攻击类别。 这些攻击不是攻击 RSA 函数的底层结构,而是侧重于 RSA 的实现。
5.1 时序攻击 (Timing Attacks)
想象有一个存储RSA私钥的智能卡,由于这张卡为了防止篡改,所以Marvin可能不能检查其中的内容,从而直接得到的密钥。但是有一个Kocher想到了一个巧妙的攻击方式:通过精确地测量这张卡执行RSA解密(或签名)所需的时间,可以快速找到私钥d。
下面,我们将解释如何使用"重复平方算法",对一个简单的RSA实现进行攻击。令
-
令
,对于 ,进行如下操作 - 如果
,令 - 令
- 如果
对于
为了发起攻击,Marvin需要智能卡对大量随机消息
攻击从
Kocher观察到当
有两种方法可以抵御攻击。最简单的是添加适当的延迟,以使模幂运算总是要花费一定的时间。第二种方法是由Rivest提出的基于盲化的方法。在解密
Kocher最近在这些线路上发现了另一种叫做功率密码分析的攻击。 Kocher表明,通过在签名生成过程中精确测量智能卡的功耗,Marvin通常可以轻松发现密钥。事实证明,在多精度乘法期间,卡的功耗高于正常值。通过测量高消耗周期的长度,Marvin可以很容易地确定在给定的迭代中卡是执行一次还是两次乘法,从而暴露出的比特位。
Kocher最近发现了另一种类似的攻击,称为能量分析攻击。Kocher指出通过精确测量智能卡在签名生成过程中的功耗,Marvin通常可以很容易地得到秘密密钥。结果表明,在多精度乘法过程中卡的功耗会高于正常值,通过测量高消耗周期的长度,Marvin可以很容易地确定在给定的迭代中,卡执行一次还是两次乘法,从而得到
5.2 随机故障 (Random Faults)
RSA的解密和签名的实现经常使用中国剩余定理来加速
其中
其中:
与两次求幂相比,CRT最后一步的运行时间可以忽略不计。p和q的长度是N的一半,由于简单的乘法实现需要平方时间,所以模p的乘法速度是模n的4倍,而且
Boneh,DeMillo和Lipton观察到使用CRT方法有内在的危险。假设在生成签名时,Bob的计算机上的一个小故障导致它在一条指令中错误计算。例如,在将寄存器中的值从一个位置复制到另一个位置时,其中一个比特位被翻转了。(故障可能是由环境电磁干扰引起的,也可能是由于罕见的硬件缺陷造成的,比如早期版本的奔腾芯片。)
Marvin得到了无效的签名给定之后可以很容易地对Bob的模数进行分解。
正如A. K. Lenstra所说,我们发现了一个新的攻击。假设在Bob生成签名时发生一个错误,那么,
因此,
要使攻击奏效,Marvin必须对
5.3 Bleichenbacher对PKCS 1的攻击 (Bleichenbacher’s Attack on PKCS 1)
设
生成的消息长度为n位,并直接使用RSA加密。包含"02"的初始块长度为16位,从上图可看出已在消息中添加了随机填充。
当Bob的机器接收到PKCS 1消息时,应用程序(例如,Web浏览器)会对其进行解密,检查初始块,并去掉随机填充。但是,一些应用程序会检查"02"初始块,如果不存在,就会返回一条错误消息,报错"无效密文"。Bleichenbacher表示这个错误消息可能导致灾难性的后果:攻击者Marvin可以使用错误消息解密他所选择的密文。
假设Marvin截获了一个针对Bob的密文
(这些攻击方式在CTF比赛中不容易实现,但是在现实生活中是完全可以存在的)
6. 总结
对RSA系统进行了20年的研究以来,产生了一些有见地的攻击,但还没有发现破坏性的攻击。到目前为止发现的攻击主要说明了在实现RSA时需要避免的陷阱,目前看来,可以信任正确的RSA密码系统实施来提供数字世界中的安全性。
我们将针对RSA的攻击分为四类:
- (1)利用系统公然误用的基本攻击
- (2)低私钥指数攻击,此种攻击非常严重,绝不能使用低私钥指数
- (3)低公钥指数攻击
- (4)对RSA系统执行时的攻击
这些持续不断的攻击说明,我们对基本数学结构的研究还是不够的。另外,Desmedt和Odlyzko、Joye和Quisquater以及DeJonge和Chaum还提出了一些额外的攻击。在整篇论文中,我们知道了通过在加密或签名之前正确填充消息可以防御许多攻击。
RSA 的前二十年催生了许多引人入胜的算法。 我希望接下来的二十年同样令人兴奋。
Comments NOTHING