Coppersmith 相关攻击

基本原理

Coppersmith 相关攻击与Don Coppersmitharrow-up-right 紧密相关,他提出了一种针对于模多项式(单变量,二元变量,甚至多元变量)找所有小整数根的多项式时间的方法。

这里我们以单变量为主进行介绍,假设

  • 模数为 N ,N 具有一个因子 $b\geq N^{\beta},0< \beta \leq 1$

  • 多项式 F 的次数为 $\delta$

那么该方法可以在$O(c\delta^5log^9(N))$ 的复杂度内找到该多项式所有的根$x_0$,这里我们要求 $|x_0|<cN^{\frac{\beta^2}{\delta}}$ 。

在这个问题中,我们的目标是找到在模 N 意义下多项式所有的根,这一问题被认为是复杂的。Coppersmith method 主要是通过 Lenstra–Lenstra–Lovász lattice basis reduction algorithmarrow-up-right(LLL)方法找到

  • 与该多项式具有相同根 $x_0$

  • 更小系数

  • 定义域为整数域

的多项式 g,由于在整数域上找多项式的根是简单的(Berlekamp–Zassenhaus),从而我们就得到了原多项式在模意义下的整数根。

那么问题的关键就是如何将 f 转换到 g 呢?Howgrave-Graham 给出了一种思路

image-20180717210921382

也就是说我们需要找到一个具有“更小系数”的多项式 g,也就是下面的转换方式

image-20180717211351350

在 LLL 算法中,有两点是非常有用的

  • 只对原来的基向量进行整数线性变换,这可以使得我们在得到 g 时,仍然以原来的 $x_0$ 为根。

  • 生成的新的基向量的模长是有界的,这可以使得我们利用 Howgrave-Graham 定理。

在这样的基础之上,我们再构造出多项式族 g 就可以了。

关于更加细节的内容,请自行搜索。同时这部分内容也会不断更新。

需要注意的是,由于 Coppersmith 根的约束,在 RSA 中的应用时,往往只适用于 e 较小的情况。

Basic Broadcast Attack

攻击条件

如果一个用户使用同一个加密指数 e 加密了同一个密文,并发送给了其他 e 个用户。那么就会产生广播攻击。这一攻击由 Håstad 提出。

攻击原理

这里我们假设 e 为 3,并且加密者使用了三个不同的模数 $n_1,n_2,n_3$ 给三个不同的用户发送了加密后的消息 m,如下

c1=m3modn1c2=m3modn2c3=m3modn3\begin{align*} c_1&=m^3\bmod n_1 \\ c_2&=m^3\bmod n_2 \\ c_3&=m^3\bmod n_3 \end{align*}

这里我们假设 $n_1,n_2,n_3$ 互素,不然,我们就可以直接进行分解,然后得到 d,进而然后直接解密。

同时,我们假设 $m<n_i, 1\leq i \leq 3$。如果这个条件不满足的话,就会使得情况变得比较复杂,这里我们暂不讨论。

既然他们互素,那么我们可以根据中国剩余定理,可得$m^3 \equiv C \bmod n_1n_2n_3$。

此外,既然 $m<n_i, 1\leq i \leq 3$,那么我们知道 $m^3 < n_1n_2n_3$ 并且 $C<m^3 < n_1n_2n_3$,那么 $m^3 = C$,我们对 C 开三次根即可得到 m 的值。

对于较大的 e 来说,我们只是需要更多的明密文对。

SCTF RSA3 LEVEL4

参考 http://ohroot.com/2016/07/11/rsa-in-ctf。

这里我们以 SCTF RSA3 中的 level4 为例进行介绍,首先编写代码提取 cap 包中的数据,如下

其次,利用得到的数据直接使用中国剩余定理求解。

得到密文,然后再次解密即可得到 flag。

题目

  • 2017 WHCTF OldDriver

  • 2018 N1CTF easy_fs

Broadcast Attack with Linear Padding

对于具有线性填充的情况下,仍然可以攻击,这时候就会使用 Coppersmith method 的方法了,这里暂不介绍。可以参考

  • https://en.wikipedia.org/wiki/Coppersmith%27s_attack#Generalizations

攻击条件

当 Alice 使用同一公钥对两个具有某种线性关系的消息 M1 与 M2 进行加密,并将加密后的消息 C1,C2 发送给了 Bob 时,我们就可能可以获得对应的消息 M1 与 M2。这里我们假设模数为 N,两者之间的线性关系如下

M1f(M2)modNM_1 \equiv f(M_2) \bmod N

其中 f 为一个线性函数,比如说 $f=ax+b$。

在具有较小错误概率下的情况下,其复杂度为 $O(elog^2N)$。

这一攻击由 Franklin,Reiter 提出。

攻击原理

首先,我们知道 $C_1 \equiv M_1 ^e \bmod N$,并且 $M_1 \equiv f(M_2) \bmod N$,那么我们可以知道 $M_2$ 是 $f(x)^e \equiv C_1 \bmod N$ 的一个解,即它是方程 $f(x)^e-C_1$ 在模 N 意义下的一个根。同样的,$M_2$ 是 $x^e - C_2$ 在模 N 意义下的一个根。所以说 $x-M_2$ 同时整除以上两个多项式。因此,我们可以求得两个多项式的最大公因子,如果最大公因子恰好是线性的话,那么我们就求得了 $M_2$。需要注意的是,在 $e=3$ 的情况下,最大公因子一定是线性的。

这里我们关注一下 $e=3$,且 $f(x)=ax+b$ 的情况。首先我们有

C1M13modN,M1aM2+bmodNC_1 \equiv M_1 ^3 \bmod N,M_1 \equiv aM_2+b \bmod N

那么我们有

C1(aM2+b)3modN,C2M23modNC_1 \equiv (aM_2+b)^3 \bmod N,C_2 \equiv M_2^3 \bmod N

我们需要明确一下我们想要得到的是消息 m,所以需要将其单独构造出来。

首先,我们有式 1

(aM2+b)3=a3M23+3a2M2b+3aM2b2+b3(aM_2+b)^3=a^3M_2^3+3a^2M^2b+3aM_2b^2+b^3

再者我们构造如下式 2

(aM2)3b3(aM2b)(a2M22+aM2b+b2)modN(aM_2)^3-b^3 \equiv (aM_2-b)(a^2M_2^2+aM_2b+b^2) \bmod N

根据式 1 我们有

a3M232b3+3b(a2M22+aM2b+b2)C1modNa^3M_2^3-2b^3+3b(a^2M_2^2+aM_2b+b^2) \equiv C_1 \bmod N

继而我们有式 3

3b(a2M22+aM2b+b2)C1a3C2+2b3modN3b(a^2M_2^2+aM_2b+b^2) \equiv C_1-a^3C_2+2b^3 \bmod N

那么我们根据式 2 与式 3 可得

(a3C2b3)3b(aM2b)(C1a3C2+2b3)modN(a^3C_2-b^3)*3b \equiv (aM_2-b)( C_1-a^3C_2+2b^3 ) \bmod N

进而我们有

aM2b=3a3bC23b4C1a3C2+2b3aM_2-b=\frac{3a^3bC_2-3b^4}{C_1-a^3C_2+2b^3}

进而

aM22a3bC2b4+C1bC1a3C2+2b3aM_2\equiv \frac{2a^3bC_2-b^4+C_1b}{C_1-a^3C_2+2b^3}

进而

M22a3bC2b4+C1baC1a4C2+2ab3=baC1+2a3C2b3C1a3C2+2b3M_2 \equiv\frac{2a^3bC_2-b^4+C_1b}{aC_1-a^4C_2+2ab^3}=\frac{b}{a}\frac{C_1+2a^3C_2-b^3}{C_1-a^3C_2+2b^3}

上面的式子中右边所有的内容都是已知的内容,所以我们可以直接获取对应的消息。

有兴趣的可以进一步阅读 A New Related Message Attack on RSAarrow-up-right 以及 paperarrow-up-right 这里暂不做过多的讲解。

SCTF RSA3

这里我们以 SCTF RSA3 中的 level3 为例进行介绍。首先,跟踪 TCP 流可以知道,加密方式是将明文加上用户的 user id 进行加密,而且还存在多组。这里我们选择第 0 组和第 9 组,他们的模数一样,解密脚本如下

得到明文

当然,我们也可以直接使用 sage 来做,会更加简单一点。

结果如下

题目

  • hitcon 2014 rsaha

  • N1CTF 2018 rsa_padding

Coppersmith’s short-pad attack

攻击条件

目前在大部分消息加密之前都会进行 padding,但是如果 padding 的长度过短,也有可能被很容易地攻击。

这里所谓 padding 过短,其实就是对应的多项式的根会过小。

攻击原理

我们假设爱丽丝要给鲍勃发送消息,首先爱丽丝对要加密的消息 M 进行随机 padding,然后加密得到密文 C1,发送给鲍勃。这时,中间人皮特截获了密文。一段时间后,爱丽丝没有收到鲍勃的回复,再次对要加密的消息 M 进行随机 padding,然后加密得到密文 C2,发送给 Bob。皮特再一次截获。这时,皮特就可能可以利用如下原理解密。

这里我们假设模数 N 的长度为 k,并且 padding 的长度为 $m=\lfloor \frac{k}{e^2} \rfloor$。此外,假设要加密的消息的长度最多为 k-m 比特,padding 的方式如下

M1=2mM+r1,0r12mM_1=2^mM+r_1, 0\leq r_1\leq 2^m

消息 M2 的 padding 方式类似。

那么我们可以利用如下的方式来解密。

首先定义

g1(x,y)=xeC1g2(x,y)=(x+y)eC2g_1(x,y)=x^e-C_1 g_2(x,y)=(x+y)^e-C_2

其中 $y=r_2-r_1$。显然这两个方程具有相同的根 M1。然后还有一系列的推导。

Known High Bits Message Attack

攻击条件

这里我们假设我们首先加密了消息 m,如下

CmdmodNC\equiv m^d \bmod N

并且我们假设我们知道消息 m 的很大的一部分 $m_0$,即 $m=m_0+x$,但是我们不知道 $x$。那么我们就有可能通过该方法进行恢复消息。这里我们不知道的 x 其实就是多项式的根,需要满足 Coppersmith 的约束。

可以参考 https://github.com/mimoo/RSA-and-LLL-attacks。

Factoring with High Bits Known

攻击条件

当我们知道一个公钥中模数 N 的一个因子的较高位时,我们就有一定几率来分解 N。

攻击工具

请参考 https://github.com/mimoo/RSA-and-LLL-attacks。上面有使用教程。关注下面的代码

其中,

  • 必须满足 $q\geq N^{beta}$,所以这里给出了$beta=0.5$,显然两个因数中必然有一个是大于的。

  • XX 是 $f(x)=q'+x$ 在模 q 意义下的根的上界,自然我们可以选择调整它,这里其实也表明了我们已知的 $q'$ 与因数 q 之间可能的差距。

2016 HCTF RSA2

这里我们以 2016 年 HCTF 中的 RSA2 为例进行介绍。

首先程序的开头是一个绕过验证的,绕过即可,代码如下

这里我们也已经得到 n,e,e2,加密后的 flag 了,如下

接下来我们来分析主程序。可以看出

我们得到的 $n=p \times q$。而 p,q 以及我们已知的 e 都在 gen_key 函数中生成。看一看 gen_key 函数

其中我们已知如下参数

k=2048e=0x10001k=2048 e=0x10001

首先,程序先得到了 1024 比特位的素数 p,并且 gcd(2,p-1)=1

然后,程序又得到了一个 1024 比特位的素数 $q_t$,并且计算 $n_t=p \times q_t$。

下面多次调用了 get_bit 函数,我们来简单分析一下

可以看出根据 dire(ction) 的不同,会得到不同的数

  • dire=1 时,程序首先计算 number 的二进制位数 sn,如果不是 8 的整数倍的话,就将 sn 增大为 8 的整数倍,然后返回 number 右移 sn-n_bit 的数字。其实 就是最多保留 numbern_bit 位。

  • dire=0 时,程序直接获取 number 的低 n_bit 位。

然后我们再来看程序

这三个操作分别做了如下的事情

  • tn_t 的最多高 k/16 位,即 128 位,位数不固定。

  • yn_t 的低 5*k/8 位,即 1280 位,位数固定。

  • p4 为 p 的最多高 5*k/16 位,即 640 位,位数不固定。

此后,程序有如下操作

利用 pi_bp4 进行了加密

其中,我们已知了密钥 key,所以只要我们有密文就可以解密。此外,可以看到的是程序是对传入的消息进行 8 字节分组,采用密码本方式加密,所以密文之间互不影响。

下面

程序将 t,u,y 拼接在一起得到 n,进而,程序得到了 q,并对 q 的低 k/16 位做了抑或,然后返回 q'

在主程序里,再一次得到了 n'=p*q'。这里我们仔细分析一下

而 p 是 k/2 位的,所以说,random 的部分最多可以影响原来的 n 的最低的 $k/2+k/16=9k/16$ 比特位。

而,我们还知道 n 的最低的 5k/8=10k/16 比特为其实就是 y,所以其并没有影响到 u,即使影响到也就最多影响到一位。

所以我们首先可以利用我们得到的 n 来获取 u,如下

虽然,这样可能会获得较多位数的 u,但是这样并不影响,我们对 u 解密的时候每一分组都互不影响,所以我们只可能影响最高位数的 p4。而 p4 的的高 8 位也有可能是填充的。但这也并不影响,我们已经得到了因子 p 的的很多部分了,我们可以去尝试着解密了。如下

解密结果如下

下面,我们直接使用 sage 来解密,这里 sage 里面已经实现了这个攻击,我们直接拿来用就好

关于 small_roots 的使用,可以参考 SAGE 说明arrow-up-right

结果如下

题目

  • 2016 湖湘杯 简单的 RSA

  • 2017 WHCTF Untitled

Boneh and Durfee attack

攻击条件

当 d 较小时,满足 $d < N^{0.292}$ 时,我们可以利用该攻击,比 Wiener's Attack 要强一些。

攻击原理

这里简单说一下原理。

首先

ed1modφ(N)/2ed \equiv 1 \bmod \varphi(N)/2

进而有

ed+kφ(N)/2=1ed +k\varphi(N)/2=1

kφ(N)/21modek \varphi(N)/2 \equiv 1 \bmod e

φ(N)=(p1)(q1)=qppq+1=Npq+1\varphi(N)=(p-1)(q-1)=qp-p-q+1=N-p-q+1

所以

k(Npq+1)/21modek(N-p-q+1)/2 \equiv 1 \bmod e

假设 $A=\frac{N+1}{2}$,$y=\frac{-p-q}{2}$ ,原式可化为

f(k,y)=k(A+y)1modef(k,y)=k(A+y) \equiv 1 \bmod e

其中

$|k|<\frac{2ed}{\varphi(N)}<\frac{3ed}{N}=3*\frac{e}{N}d<3\frac{e}{N}*N^{delta}$

$|y|<2*N^{0.5}$

y 的估计用到了 p、q 比较均匀的假设。这里 delta 为预估的小于 0.292 的值。

如果我们求得了该二元方程的根,那么我们自然也就可以解一元二次方程 $N=pq,p+q=-2y$ 来得到 p 与 q。

更加具体的推导,参考 New Results on the Cryptanalysis of Low Exponent RSA.

攻击工具

请参考 https://github.com/mimoo/RSA-and-LLL-attacks 。上面有使用教程。

2015 PlaidCTF Curious

这里我们以 2015 年 PlaidCTF Curious 为例进行介绍。

首先题目给了一堆 N,e,c。简单看一下可以发现该 e 比较大。这时候我们可以考虑使用 Wiener's Attack,这里我们使用更强的目前介绍的攻击。

核心代码如下

结果如下

2019 Defcon Quals ASRybaB

题目大概意思是,我们接收三对 RSA ,然后需要求出 d,然后对给定的数字 v[i] 加密,发送给服务器,只要时间在一定范围内,940s,即可。那难点自然在 create_key 函数了。

我们可以简单看看这个到底是在干啥

基本可以猜出来这是在生成 n,e,d,其实和我们最初的预期也差不多。我们来直接反编译一下

可以发现 STOP_CODE,有点猫腻,如果仔细看最初的反汇编的话,我们可以发现最前面的那部分代码是在混淆

一直到

前面的都没有什么作用,感觉是出题者故意修改了代码。仔细分析一下这部分代码,感觉像是两部分

正好是第 25 行和第 26 行,大概猜一猜,感觉两个都是 x=7/0,所以就想办法把这部分的代码修复一下,接下来就是定位这部分代码了。根据手册可以知道 STOP_CODE 是 0,从而我们可以定位第 25 行语句到 26 行语句为 t[6:26],他们分别都是 10 字节(6-15,16-25)。

从而我们可以修复原 code

可以看到生成的 d 是故意超了 0.292 的,不过我们可以发现 ppp 范围很小,实际上我们可以测试得到这个范围的素数为 125 个。并且

所以其实这里就乘了一个数,那么我们其实就可以枚举一下乘了什么,并修改 e1=e*ppp,其实就回归到标准的 Boneh and Durfee attack。

但是,如果我们直接使用 https://github.com/mimoo/RSA-and-LLL-attacks 的脚本也不行,必须得提高 m,基本得提到 8,这样仍然不是很稳定。

如果仔细尝试尝试的话,就会发现 e1>N,这看起来问题不大,但是原脚本里假设的数值是 e<N 的,所以我们需要进行适当的修改预估的上下界

根据上述推导,上下界应该为

$|k|<\frac{2ed}{\varphi(N)}<\frac{3ed}{N}=3*\frac{e}{N}d<3\frac{e}{N}*N^{delta}$

$|y|<2*N^{0.5}$

最后主要修改了 m 和 X 的上界

最后可以得到结果

不得不说这个题目,真的是需要核服务器。。

参考资料

  • Survey: Lattice Reduction Attacks on RSA

  • An Introduction to Coppersmith’s method and Applications in Cryptology

Last updated