RSA攻击方式总结

1.模数分解

1).解题思路

​ a).找到RSA算法中的公钥(e,n)

​ b).通过n来找到对应的p和q,然后求得φ(n)

​ c).通过gmpy2.invert或者gmpy2.gcdext可以求得e的逆元d

​ d).通过pow函数将密文解密(pow(a,b,c)函数的速度比直接写a**b mod c 要快)

2).直接分解n

​ a).通常情况下,如果n的长度小于256bit(二进制),那么可以通过本地的工具进行分解(RSATool2v17)

​ b).如果n的长度较大,可以尝试在相关网站上进行查询。这些网站上存储着已经分解过的n对应的p和q

​ c).通常,如果n的长度大于512bit,可以考虑下面的方法进行解题

3).利用公约数(模不互素攻击)

​ a).如果题目中两次公钥加密给出了n1和n2有相同的素因子,那么可以通过gmpy2.gcd求出素因子p,然后在分别对n1和n2求出q1和q2

​ b).这种需要利用公约数的题目,通常情况下给出的n长度都在2048bit,4096bit,无法强行破解

4).一些难度比较大的分解方法

​ a).针对大整数的分解有很多种算法,性能上各有优异,有指数级分解方法:Fermat平方差方法,Pollard 方法(ρ,ρ-1)(Pollard's rho algorithm),二次型分解算法,椭圆曲线分解法(ECM)和亚指数级分解方法:连分数分解算法,筛法(二次筛选法(QS),一般数域筛法(GNFS))等等。

​ b).但是,有一个开源项目yafu可以自动化的完成分解,不论n的大小(密码学工具使用)

5).做题过程中get到的方法,有可能是方法4里面的包括的

  1. 知道了\(\phi (n)\),就可以开方:

    这个算法涉及两个点,开方后的取值的大小 Q, Q<p<q, 或 p<Q<q

    1.p<Q<q

    假设 p=7,q=11,,则(p-1)*(q-1)=60,

    iroot(60,2)[0] = 7 (iroot()表示开根号,[0]表示取整数部分)

    所以用sympy.next(7),就可以求得7后面的一个素数11

    2.Q<p<q

    假设 p=3,q=5, 则(p-1)*(q-1)=8,

    iroot(8,2)[0] = 2 (iroot()表示开根号,[0]表示取整数部分)

    所以用sympy.next(2),就可以求得2后面的一个素数3

    3.

    虽然Q取值范围不定,但是我们可以肯定的是,Q一定小于max(p,q),即p,q中最大的那个数。所以通过nextprime(Q),就可以求得p,q中任意的值。再用已知的 (ed-1)//k == (p-1)(q-1),就可以求得(p-1)或是(q-1)的值了。最后再进行素性检测就可以了

    原文地址:BUUCTF RSA题目全解2的第十题

2.低加密指数攻击

​ RSA中,e也被称作加密指数,由于e是从(1,φ(n))中任意选取的,有些时候为了缩短加密时间,可以适当的选择较小的e。

1).e=3的小明文攻击(暴力开方破解)

​ a).当e=3时,如果明文过小,导致明文的三次方仍然小于n,那么直接对密文三次开方,就可以得到明文(a如果小于n,则a mod n==a)

​ b).如果明文的三次方大于n,但是不是很大,就可以设k,有:

\[c=m^e+kn
\]

​ 对k进行爆破,若 \(c-kn\) 可以开三次根式,那么可以直接得到明文

​ c).使用加密指数e=\(2^{16} +1\)=65537(费马素数[1])可以避免一些对e=3的攻击

​ d).也可以将明文进行填充

2).低加密指数广播攻击(Johan Håstad广播攻击)

​ a).如果选取的加密指数e较小,且给多个接收方用这个e发送相同的明文(n不同),那么就可以进行广播攻击

​ b).当收集到的加密消息个数大于或等于e时,有(假设e=3)如果是根据中国剩余定理,那么加密消息至少得有三个(一个和两个不能得出一组确切的解)

\[\begin{cases} c_1\equiv m^e (mod\ n_1)\\ c_2\equiv m^e (mod\ n_2)\\ c_3\equiv m^e (mod\ n_3)\end{cases}
\]

​ 则根据中国剩余定理,可知:

\[m^e=(\sum_{i=1}^{n}{c_i*N_i*N_i^{-1}})\%N
\]

​ 对m开e次方根,即可求得明文。

​ 注:\(N_i^{-1}\)是\(N_i\)模\(n_i\)的逆元

3)Coppersmith短填充攻击

3.低解密指数攻击

​ a).同样的,低解密指数通常会加快解密的速度,但是也会带来安全隐患

​ b).如果解密指数\(d<\frac{1}{3}N^\frac{1}{4}\),那么一种由Wiener提出的基于连分式的算法可以解出该解密指数(使用了连分式的经典数论理论以及如何找到用有理数对二次无理数最合理的逼近方法)。工具rsa_wiener_attack

​ c).再后来,Boneh指出,使用小于\(\sqrt{N}\)的解密指数的系统可能容易受到此类攻击

由图可知,解密指数的攻击范围被提高了

4.共模攻击

​ 如果出现了用相同的模数n来加密相同的明文m(加密指数e不一样),则会得到

\[\begin{cases} c_1\equiv m^{e_1} (mod\ n) \\ c_2\equiv m^{e_2} (mod\ n) \end{cases}
\]

​ 此时

​ a).可以利用米勒公式,通过一个人的秘钥(\(e_i,d_i\))分解n得到p,q,从而可以通过别人的公钥来计算别人的私钥

​ b).如果两个加密指数互素,那么根据扩展你欧几里得方程可知,有:

\[e_1s_1+e_2s_2=\gcd(e_1,e_2)=1
\]

​ 那么可得

\[\begin{equation}
\begin{aligned}
(c_1^{s_1}*c_2^{s_2})\%n
&=((m^{e_1}\%n)^{s_1}*(m^{e_2}\%n)^{s_2})\%n \\
&=(m^{(e_1s_1+e_2s_2)})\%n \\
&=m\%n
\end{aligned}
\end{equation}
\]

​ 所以,可以得到

\[c_1^{s_1}*c_2^{s_2}\equiv m (mod\ n)
\]

​ 所以,我们在完全不知道密钥的前提下,得到了明文m

​ 注意:在Python的pow函数中,指数不可以为负数,而\(s_1\),\(s_2\)中必然有一个是负数,则需要将对应的c取反,再用-s作为指数进行运算[2]

k,s1,s2=gmpy2.gcdext(e1,e2)
if s1<0:
s1=-s1
c1=gmpy2.invert(c1,n)
else:
s2=-s2
c2=gmpy2.invert(c2,n)
m=pow(c1,s1,n)*pow(c2,s2,n)%n #虽然不知道为什么,但是好像这样写运算会很快 print("所求明文为:",m)
print(long_to_bytes(m))

5.前向搜索攻击[3]

如果知道所有可能消息的集合,而且该集合相对来说比较小,则攻击者只需要将所有的消息进行加密直到找到一个匹配者。例 如,如果已知消息为‘YES’或‘NO’,那么只需要计算一次就知道哪一个是明文。因此,特别是在比较短小的消息的情况下,应该通过在前面或者后面添加随机位数的填充信息。

6.教科书RSA的两个性质和攻击方法[4]

教科书RSA是确定性的,意即同样的明文m总是生成同样的密文c。这就使密码本攻击成为可能:攻击者预先计算出全部或部分的\(m\to c\) 对照表保存,然后搜索截获的密文匹配即可。确定性也意味着教科书RSA不是语义安全的,密文会泄露明文的某些信息。密文重复出现,表明发送方在重复发送相同的消息。

教科书RSA具有延展性 (malleable),对密文进行特定形式的代数运算,结果会反映到解密的明文中。比如有两段明文 \(m_1\)和\(m_2\),加密后产生\(c_1= m_1^{e}\%N\)和\(c_2= m_2^e\%N\),那么(\(c_1*c_2\))解密会得到什么?看如下等式:

\[(c_1*c_2)^d\equiv m_1^{ed}*m_2^{ed}\equiv m_1*m_2(mod\ N)
\]

所以两段密文的乘积解密后得到的明文,等于两段明文的乘积。这一特性对一般的RSA加密系统是有害的,它为选择密文攻击 (chosen-ciphertext attack) 提供了机会。下面举例两种攻击场景:

1.设想有一个RSA解密机可以用内部保存的私钥(N,d)解密消息。基于安全考虑,解密机会拒绝同样的密文重复输入。攻击者马文发现一段密文,直接输入到解密机被拒绝,因为密文c以前被解密过。马文找到一种办法破解。他自己准备一段明文,用公钥(N,e)加密生成新的密文\(c'=r^ec\%N\),然后将密文\(c'\)输入到解密机。解密机没有解过这一段新的密文,所以不会拒绝。解密的结果是

\[m'\equiv (c')^d\equiv r^{ed}c^d\equiv rm(mod\ N)
\]

现在马文有了\(m'\),他用公式\(m\equiv m'r^{-1}(mod\ N)\)就可以计算出c对应的m

2.假设马文想让鲍勃在一段消息\(m\)上签名,但是鲍勃在看过消息内容后拒绝了。马文可以使用称为盲签名的攻击手段可以达成他的目标。他挑选一段随机的消息\(r\),生成 \(m'=r^em\%N\),然后把\(m'\)拿给鲍勃签名。鲍勃可能觉得\(m'\)无关紧要,就签了。鲍勃签名的结果是\(s'=(m')^d\%N\)。现在马文用公式\(s=s'r^{-1}\%N\)就拿到了鲍勃对原来消息的签名。为什么?原因是

\[s^e\equiv (s')^er^{-e}\equiv(m')^{ed}r^{-e}\equiv m(mod\ N)
\]

7.其它常见的题型总结

​ 1).给出了dp、dq的题

​ 首先明确dp、dq是什么:

\[dp= d\%(p-1) \\ dq=d\%(q-1)
\]

情况1:dp、dq都给出来了

​ 解决方法:

\[\begin{aligned}
&m_1\equiv c^{dq}(mod\ q)\\&m_2\equiv c^{dp}(mod\ p)\\&m\equiv (((m_2-m_1)*(p-1)\%q)*p+m_1)\%n
\end{aligned}
\]

​ 证明:已知\(m\equiv c^{d}(mod\ n)\)​,可得到\(m=c^{d}+k*n\)​

​ 又因为\(n=p*q\),可得\(m=c^{d}+p*q*k\),对它分别取余p,q

​ 可得\(m_1\equiv c^{d}(mod\ p)\)(1),\(m_2\equiv c^{d}(mod\ q)\)(2)

​ 式(1)可以变形为\(c^{d}=kp+m_1\),带入(2),可得\(m_2\equiv (kp+m_1)(mod\ q)\)

​ 两边同时减去\(m_1\),可得\((m_2-m_1)\equiv kp(mod\ q)\)

​ 因为p,q互素(\(gcd(p,q)=1\)),可以求得p的逆元,得到

\[(m_2-m_1)*p^{-1}\equiv k(mod\ q)
\]

​ 将它变形为

\[k\equiv (m_2-m_1)*p^{-1}(mod\ q)
\]

​ 然后与上面(1)的变形合并,可得

\[c^{d}=((m_2-m_1)*p^{-1}(mod\ q))*p+m_1
\]

​ 将\(m\equiv c^{d}(mod\ n)\),得到

\[m\equiv ((m_2-m_1)*p^{-1}(mod\ q))*p+m_1(mod\ n)\ \ (\alpha)
\]

​ 现在根据费马小定理[5]可以将dp、dq带入\(m_1\)、\(m_2\)中得到

\[m_1\equiv c^{dq}(mod\ q)\ \ (\beta)\\m_2\equiv c^{dp}(mod\ p)\ \ (\gamma)
\]

​ 这一步带入的证明见注释[6]

​ 则式子\((\alpha)(\beta)(\gamma)\)即为所求。

from Crypto.Util.number import long_to_bytes
c=int(input("请输入密文c"))
n=int(input("请输入n(不存在请输入0)"))
#存在给出p,q没有给出n的情况
p=int(input("请输入p(不存在请输入0)"))
q=int(input("请输入q(不存在请输入0)"))
dp=int(input("请输入dp"))
dq=int(input("请输入dq"))
if n==0:
n=p*q
m1=pow(c,dq,q)
m2=pow(c,dp,p)
k=(m2-m1)*(p-1)%q
m=k*p+m1%n
print("所求明文为:",m)
print(long_to_bytes(m))

情况2:只给出了dp/dq的题

​ 假设给出的是dp,则有\(dp=d\%(p-1)\),变形可得

\[d*e=k_1*(p-1)*e+dp*e
\]

​ 变形后与式子\(d*e\equiv 1(mod\ \phi(n))\)结合,可得

\[\begin{aligned}
k_1*e*(p-1)+dp*e&=1+k_2*(p-1)*(q-1)\\
dp*e&=[k_2*(p-1)*(q-1)+1]-[k_1*e*(p-1)]+1\\
dp*e&=[k_2*(q-1)-k_1*e]*(p-1)+1
\end{aligned}
\]

​ 设:X=\(k_2*(q-1)-k_1*e\),有\(dp*e=X*(p-1)+1\),因为\(dp=d\%(p-1)\),所以\(dp<p-1\),可得\(X<e\),\(X\in(0,e)\)和式子\((p-1)=\frac{dp*e-1}{X}\)

​ 则有遍历区间(0,e),找到一个X可以整除(不是被整除)(dp*e-1),且对应的p能够整除n的情况,然后求出q,即可得到明文。

​ 给出dq同理。

for X in range(1,e):
if (dp*e-1)%X == 0:
if n%(((dp*e-1)/X)+1)==0:
p=((dp*e-1)/X)+1
q=n/(((dp*e-1)/X)+1)
phi = (p-1)*(q-1)
d = gmpy2.invert(e,phi)%phi
import gmpy2
e = 65537
n = 248254007851526241177721526698901802985832766176221609612258877371620580060433101538328030305219918697643619814200930679612109885533801335348445023751670478437073055544724280684733298051599167660303645183146161497485358633681492129668802402065797789905550489547645118787266601929429724133167768465309665906113
dp = 905074498052346904643025132879518330691925174573054004621877253318682675055421970943552016695528560364834446303196939207056642927148093290374440210503657 c = 140423670976252696807533673586209400575664282100684119784203527124521188996403826597436883766041879067494280957410201958935737360380801845453829293997433414188838725751796261702622028587211560353362847191060306578510511380965162133472698713063592621028959167072781482562673683090590521214218071160287665180751 for X in range(2,e):
if (dp*e-1)%X == 0:
if n%(((dp*e-1)//X)+1)==0: #这里和下面的//如果换成/就会出现OverflowError: int too large to convert to float的问题
p=((dp*e-1)//X)+1
q=n//(((dp*e-1)//X)+1)
phi = (p-1)*(q-1)
d = gmpy2.invert(e,phi)%phi
m=pow(c,d,n)

参考来源:

  1. 【技术分享】CTF中RSA的常见攻击方法

  2. 《密码学导引》(美)Paul Garrett著

  3. 《现代密码分析学——破译高级密码的技术》(美)Christopher Swenson著

  4. CTF-RSA1(已知p、q、dp、dq、c)

  5. RSA的攻与防(一)

  6. RSA的dp泄露 [BUUCTF] RSA2


  1. 费马素数:是一类特殊形式的数,形如\(2^m+1\)​的数如果是素数,那么它被称作费马素数。与之相对的是梅森素数:形如\(2^n-1\)​的素数

  2. \(c_1^{s}=(c_1^{-1})^{-s}\%n\)

  3. 这一段来自参考来源2

  4. 这一段来自参考来源5

  5. 费马小定理:如果有条件:1). p为素数,2). \(gcd(a,p)=1\),则有式子\(a^{p-1}\equiv1(mod\ p)\)成立。这个定理也常常用来计算乘法逆元:\(a*a^{p-2}\equiv1(mod\ p)\),则\(a^{p-2}\)是a的乘法逆元

  6. 证明:由于费马小定理,可知在c和p互素的情况下(p必然是素数),那么将式子\(d=dp+k*(p-1)\)带入式子\(m_2\equiv c^d (mod\ p)\),可得 \(m_2\equiv c^{dp+k(p-1)}(mod\ p)\),\(m_2\equiv c^{dp}*c^{k(p-1)}(mod\ p)\)。因为\(c^{(p-1)}\equiv 1(mod\ p)\),可得:\(m_2\equiv c^{dp}*(1)^k (mod\ p)\),\(m_2\equiv c^{dp}(mod\ p)\),根据对称性,可知\(m_1\)同理。

简单RSA攻击方式的更多相关文章

  1. WEB开发中一些常见的攻击方式及简单的防御方法

    WEB开发中一些常见的攻击方式及简单的防御方法 转载:http://blog.csdn.net/seven__________7/article/details/70896913

  2. ARP攻击的发现、攻击原理、攻击方式、防护,竟然这么简单?!

    ARP协议概述 ARP协议(address resolution protocol)地址解析协议. 一台主机和另一台主机通信,要知道目标的IP地址,但是在局域网中传输数据的网卡却不能直接识别IP地址, ...

  3. web上常见的攻击方式及简单的防御方法

    SQL注入最常见的攻击方式,所谓SQL注入,就是通过把SQL命令插入到Web表单提交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令,比如先前的很多影视网站泄露VIP会员密码大 ...

  4. JWT原理及常见攻击方式

    JWT的全称是Json Web Token.它遵循JSON格式,将用户信息加密到token里,服务器不保存任何用户信息,只保存密钥信息,通过使用特定加密算法验证token,通过token验证用户身份. ...

  5. 接口自动化测试的"开胃小菜"---简单黑客攻击手段

    Web应用系统的小安全漏洞及相应的攻击方式 接口自动化测试的"开胃小菜" 1   写作目的 本文讲述一个简单的利用WebAPI来进行一次基本没有破坏力的“黑客”行为. 主要目的如下 ...

  6. [转]浅谈CSRF攻击方式

    在CSDN中看到对CSRF攻击的原理及防护文章,讲解浅显易懂,特转之: 来源:http://blog.csdn.net/fationyyk/article/details/50833620 一.CSR ...

  7. 浅谈CSRF攻击方式

    一.CSRF是什么? CSRF(Cross-site request forgery),中文名称:跨站请求伪造,也被称为:one click attack/session riding,缩写为:CSR ...

  8. CSRF(跨站请求伪造)攻击方式

    一.CSRF是什么? CSRF(Cross-site request forgery),中文名称:跨站请求伪造,也被称为:one click attack/session riding,缩写为:CSR ...

  9. 【转】浅谈常用的几种web攻击方式

    浅谈常用的几种web攻击方式 一.Dos攻击(Denial of Service attack) 是一种针对服务器的能够让服务器呈现静止状态的攻击方式.有时候也加服务停止攻击或拒绝服务攻击.其原理就是 ...

随机推荐

  1. docker——nginx运行起不来或者说起来了又挂了

    记得刚开始玩docker的时候,想着docker上运行一个nginx代理,于是写了个Dockerfile: FROM nginx:latest WORKDIR . COPY demo.conf /et ...

  2. linux 设置开机自动启动应用

    作为一个开发,项目现在一般都是部署在虚拟机上的linux,数据库也是按照在l虚拟机上的linux,一旦关机了,在开机程序都没打开,又要一个个去开,很麻烦,所以现在我现在使用supervisor去做一个 ...

  3. Pytest_测试用例的执行方式(2)

    在pytest框架中,编写测试用例有如下约束: 所有的测试用例文件名都需要满足test_*.py格式或*_test.py格式. 在测试用例文件中,测试类以Test开头,并且不能带有__init__方法 ...

  4. mysql yum无法安装的原因

    今天在centos7 安装mysql时,无法yum安装,报错缺少插件,原因是:在安装centos时选择了别的服务器,重新安装为网页服务器就安装成功. 来自为知笔记(Wiz)

  5. java mapreduce实现网站PV分析

    原文链接: https://www.toutiao.com/i6765677128022229517/ PV 是Page Views的缩写,即页面浏览量,用户每一次对网站中的每个网页访问均被记录一次. ...

  6. 学习笔记--Java标识符

    Java标识符 /** * 关于 Java 语言当中的标识符 * * 1. 什么是标识符? * - 在 Java 源程序当中凡是程序员有权利自己命名 * - 标识符可以标识(类名.方法名.变量名.常量 ...

  7. HDU 2041 超级楼梯 (斐波那契数列 & 简单DP)

    原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=2041 题目分析:题目是真的水,不难发现规律涉及斐波那契数列,就直接上代码吧. 代码如下: #inclu ...

  8. Choregraphe 2.8.6.23虚拟Nao机器人Socket is not connected

    Traceback (most recent call last): File "c:/Users/fengmao/OneDrive - University of Wollongong/J ...

  9. 多种语言tcp编程

    再次强调,最好socket编程 c#的tcpclient等封装无法对接android的socket服务器 c#的tcpclient等封装可对接java的socket服务器 python socket服 ...

  10. 搭建服务器之www-安装配置

    www服务器,使用软件Apache,服务守护进程为httpd,以下为安装配置过程: 1.首先yum install httpd,会下载安装Apache软件,可以用apachectrl -v查看版本,发 ...