CTF中RSA攻击方法总结

RSA

近期因为一些比赛以及其他原因,总结了一些RSA方面的东西,于是在这里与大家分享,希望大家能有所收获,如有不当之处敬请批评指正。

0x01 前言

这里就不讨论数论的基础了,进行RSA的题目解答,至少要懂得基本的数论知识的,如果不了解数论的基本知识的话,网上相关内容还是挺多的。

RSA基于一个简单的数论事实,两个大素数相乘十分容易,将其进行因式分解确实困难的。在量子计算机还没有成熟的今天,RSA算法凭借其良好的抵抗各种攻击的能力,在公钥密码体制中发挥着中流砥柱的作用。然而即便RSA算法目前来说是安全可靠的,但是错误的应用场景,错误的环境配置,以及错误的使用方法,都会导致RSA的算法体系出现问题,从而也派生出针对各种特定场景下的RSA攻击方法。

本文针对一些在CTF中常见的RSA攻击方法,从如何识别应该应用那种方法以及如何去解题来介绍CTF中的RSA题目的常见解法。

RSA算法描述

RSA算法涉及三个参数,n,e,d,私钥为n,d,公钥为n,e。

其中n是两个大素数p,q的乘积。

d是e模 $varphi(n)$的逆元,$ varphi(n) $是n的欧拉函数。

$$sh(x)=\frac{e^x+e^{-x}}{2}$$

c为密文,m为明文,则加密过程如下:

$ cequiv m^e mod n $

解密过程如下:

$ mequiv c^d$ $mod$ $n$

n,e是公开的情况下,想要知道d的值,必须要将n分解计算出n的欧拉函数值,而n是两个大素数p,q的乘积,将其分解是困难的。

RSA题目类型

在CTF竞赛中,RSA理所当然处在CRYPTO中居多。而且RSA作为典型的加密算法,其出镜率可谓相当高,基本上所有比赛都会有几道RSA的题目出现。

数据处理

在进行做题之前,我们要将数据处理成可以做题的模式。基本上来说,RSA的题目都是围绕着c,m,e,d,n,p,q这几个参数展开的,但是题目一般不会直接给这种样子的参数,而是通过别的方式给出,这里就需要我们使用一些工具或者自己手工将这些参数提取出来。

pem文件针对此类文件可以直接使用openssl提取,大概使用过的方式有:

openssl   rsautl -encrypt -in FLAG -inkey public.pem -pubin -out flag.enc
openssl   rsa -pubin -text -modulus -in warmup -in public.pem

pcap文件:针对此类文件可以使用wireshark follow一下。这种问题一般都是写了一个交互的crypto系统,所以可能产生多轮交互。

PPC模式:这种模式是上述pcap文件的交互版,会给一个端口进行一些crypto的交互,参数会在交互中给出。

第二个需要处理的就是明密文,这个方法多多,不多赘述。

0x02 模数分解

说一说

解决RSA题目最简单,最暴力,最好使的方法就是分解模数n。如果能够将n分解成功,成功得到p,q的取值,那么可求n的欧拉函数的值。

$ varphi(n)=(p-1)(q-1) $

而通过e,d与n的欧拉函数满足如下关系:

$ed=1$ $mod$ $varphi(n) $

通过欧几里得算法可以通过e与n的欧拉函数的值轻易求出d,从而计算出解密密钥。

即在知道e,p,q的情况下,可以解出d:

自己写,或者gmpy2 invert
def egcd(a, b):
    if a == 0:
      return (b, 0, 1)
    else:
      g, y, x = egcd(b % a, a)
      return (g, x - (b // a) * y, y)
  def modinv(a, m):
    g, x, y = egcd(a, m)
    if g != 1:
      raise Exception('modular inverse does not exist')
    else:
      return x % m

modinv函数即为求模拟的函数,在知道e,p,q的情况下,可以:

d=modinv(e,(p-1)*(q-1))

即可求出解密密钥。

写到这里,要提出一个细节问题,在利用python进行rsa的题目求解过程中:

$ cequiv m^e mod n $

此类运算需要使用pow函数来进行求解,而不是直接m**e % n,这样会慢死的。Python在处理此类运算进行了优化。比如刚才在已知p,q的时候利用modinv函数求出了d,然后就可以利用pow函数求出明文:

m=pow(c,d,n)

例题:

https://www.jarvisoj.com (very easy RSA)

题目中直接给了p,q,e。

可以直接求出d:

import gmpy2
from gmpy2 import mpz
p = mpz(3487583947589437589237958723892346254777)
q = mpz(8767867843568934765983476584376578389)
e = mpz(65537)
d = gmpy2.invert(e, (q-1)*(p-1))
print d

直接分解n

介绍:

素数分解问题是困难的,但是可以通过计算机进行暴力分解。1999年,名为Cray的超级计算机用了5个月时间分解了512bit的n。2009年,一群研究人员成功分解了768bit的n。2010年,又提出了一些针对1024bit的n的分解的途径,但是没有正面分解成功。通常意义上来说,一般认为2048bit以上的n是安全的。现在一般的公钥证书都是4096bit的证书。

如果n比较小,那么可以通过工具进行直接n分解,从而得到私钥。如果n的大小小于256bit,那么我们通过本地工具即可爆破成功。例如采用windows平台的RSATool2v17,可以在几分钟内完成256bit的n的分解。

如果n在768bit或者更高,可以尝试使用一些在线的n分解网站,这些网站会存储一些已经分解成功的n,比如:http://factordb.com

通过在此类网站上查询n,如果可以分解或者之前分解成功过,那么可以直接得到p和q。然后利用前述方法求解得到密文。

识别:

此类问题一般是分值较小的题目,提取出n之后可以发现n的长度小于等于512bit,可以直接取分解n。如果大于512bit,建议在使用每个题目都用后面所说的方法去解题。

例题:

比如在某次竞赛中,发现:

n=87924348264132406875276140514499937145050893665602592992418171647042491658461

利用factordb分解:

利用公约数

介绍:

如果在两次公钥的加密过程中使用的$n_1$ 和$n_2$具有相同的素因子,那么可以利用欧几里得算法直接将$n_1$和$n_2$分解。

通过欧几里得算法可以直接求出$n_1$和$n_2$的最大公约数p:

$(n1,n2)=p$

可以得出:

$n_1=p$$q_1$

$n_2=p$$q_2$

直接分解成功。而欧几里得算法的时间复杂度为:O(log n)。这个时间复杂度即便是4096 bit也是秒破级别。

def gcd(a, b):
   if a < b:
     a, b = b, a
   while b != 0:
     temp = a % b
     a = b
     b = temp
   return a

识别此类题目,通常会发现题目给了若干个n,均不相同,并且都是2048bit,4096bit级别,无法正面硬杠,并且明文都没什么联系,e也一般取65537。 识别:

例题:

在一个题目中,你拿到了两个n,e都为65537,两个n分别为:

n1=9051013965404084482870087864821455535159008696042953021965631089095795348830954383127323853272528967729311045179605407693592665683311660581204886571146327720288455874927281128121117323579691204792399913106627543274457036172455814805715668293705603675386878220947722186914112990452722174363713630297685159669328951520891938403452797650685849523658191947411429068829734053745180460758604283051344339641429819373112365211739216160420494167071996438506850526168389386850499796102003625404245645796271690310748804327
n2=13225948396179603816062046418717214792668512413625091569997524364243995991961018894150059207824093837420451375240550310050209398964506318518991620142575926623780411532257230701985821629425722030608722035570690474171259238153947095310303522831971664666067542649034461621725656234869005501293423975184701929729170077280251436216167293058560030089006140224375425679571181787206982712477261432579537981278055755344573767076951793312062480275004564657590263719816033564139497109942073701755011873153205366238585665743

通过直接分解,上factordb都分解失败。通过尝试发现:

print gcd(n1,n2)

打印出:

1564859779720039565508870182569324208117555667917997801104862601098933699462849007879184203051278194180664616470669559575370868384820368930104560074538872199213236203822337186927275879139590248731148622362880471439310489228147093224418374555428793546002109

则此致即为两个n共有的素因子p,然后进一步求出q,求解完毕。

Fermat方法与Pollard rho方法

介绍:

针对大整数的分解有很多种算法,性能上各有优异,有Fermat方法,Pollard rho方法,试除法,以及椭圆曲线法,连分数法,二次筛选法,数域分析法等等。其中一些方法应用在RSA的攻击上也有奇效。

在p,q的取值差异过大,或者p,q的取值过于相近的时候,Format方法与Pollard rho方法都可以很快将n分解成功。

此类分解方法有一个开源项目yafu将其自动化实现了,不论n的大小,只要p和q存在相差过大或者过近时,都可以通过yafu很快地分解成功。

识别:

在直接分解n无望,不能利用公约数分解n之后,都应该使用yafu去试一下。

例题:

https://www.jarvisoj.com (Medium RSA)

此题首先从pem中提取N和e,然后上yafu,直接分解成功。

0x03 低加密指数攻击

在RSA中e也称为加密指数。由于e是可以随意选取的,选取小一点的e可以缩短加密时间,但是选取不当的话,就会造成安全问题。

e=3时的小明文攻击

介绍:

当e=3时,如果明文过小,导致明文的三次方仍然小于n,那么通过直接对密文三次开方,即可得到明文。

即:

$ cequiv m^e$ $mod$ $n$

如果e=3,且$ m^e<{n} $,那么:

$ c= m^e,$ $e=3$

$ m=sqrt[3]{c}$

如果明文的三次方比n大,但是不是足够大,那么设k,有:

$ c= m^e+kn$

爆破k,如果$ c-kn $能开三次根式,那么可以直接得到明文。

识别:

推荐在e=3的时候首先尝试这种方法。

例题:

https://www.jarvisoj.com (Extremely hard RSA)

关键代码如下:此题通过不断给明文+n开三次方即可求得:

i=0
   while 1:
   if(gmpy.root(c+i*N, 3)[1]==1):
     print gmpy.root(c+i*N, 3)
     break
   i=i+1

低加密指数广播攻击

介绍:

如果选取的加密指数较低,并且使用了相同的加密指数给一个接受者的群发送相同的信息,那么可以进行广播攻击得到明文。

即,选取了相同的加密指数e(这里取e=3),对相同的明文m进行了加密并进行了消息的传递,那么有:

$ c_1equiv m^e$ $mod$ $n_1$

$ c_2equiv m^e$ $mod$ $n_2$

$ c_3equiv m^e$ $mod$ $n_3$

对上述等式运用中国剩余定理,在e=3时,可以得到:

$ c_xequiv m^3$ $mod$ $n_1n_2n_3$

通过对$ c_x $进行三次开方可以求得明文。

识别:

这个识别起来比较简单,一般来说都是给了三组加密的参数和明密文,其中题目很明确地能告诉你这三组的明文都是一样的,并且e都取了一个较小的数字。

例题:

SCTF2016,CODE300

题目第二轮中通过流量包的方式给了广播攻击的参数。

这里我就不卖萌了,直接给国外类似一题的网址:http://codezen.fr/2014/01/16/hackyou-2014-crypto-400-cryptonet

Coppersmith定理攻击

Coppersmith定理指出在一个e阶的mod n多项式f(x)中,如果有一个根小于$ n^frac{1}{e} $,就可以运用一个O(log n)的算法求出这些根。

这个定理可以应用于RSA算法。如果e = 3并且在明文当中只有三分之二的比特是已知的,这种算法可以求出明文中所有的比特。

并未找到真题。

0x04 低解密指数攻击

介绍:

与低加密指数相同,低解密指数可以加快解密的过程,但是者也带来了安全问题。Wiener表示如果满足:

$ d<frac{1}{3}gn^frac{1}{4}$

那么一种基于连分数(一个数论当中的问题)的特殊攻击类型就可以危害RSA的安全。此时需要满足:

$q<$$p$$<2q$

如果满足上述条件,通过Wiener Attack可以在多项式时间中分解n。

rsa-wiener-attack的攻击源码开源在了github中,采取python编写,可以很容易使用。

识别:

非常简单,e看起来很大就行了。

例题:

直接github用工具就行。https://github.com/pablocelayes/rsa-wiener-attack

这里注意一个细节问题,如果在运行脚本的时候报错,请在脚本前加上:

import   sys
sys.setrecursionlimit(10000000)

0x05 共模攻击

介绍:

如果在RSA的使用中使用了相同的模n对相同的明文m进行了加密,那么就可以在不分解n的情况下还原出明文m的值。

即:

$ c_1equiv m^{e_1}$ $mod$ $n$

$ c_2equiv m^{e_2}$ $mod$ $n$

此时不需要分解n,不需要求解私钥,如果两个加密指数互素,就可以通过共模攻击在两个密文和公钥被嗅探到的情况下还原出明文m的值。

过程如下,首先两个加密指数互质,则:

$ (e_1,e_2)=1 $

即存在$ s_2 $,$ s_2 $使得:

$ s_1e_1+s_2e_2=1 $

又因为:

$ c_1equiv m^{e_1}$ $mod$ $n$

$ c_2equiv m^{e_2}$ $mod$ $n$

通过代入化简可以得出:

$c_1{s_1}c_2{s_2}equiv m$ $mod$ $n$

明文解出。

识别:

非常简单,若干次加密,每次n都一样,明文根据题意也一样即可。

例题:

https://www.jarvisoj.com (very hard RSA)

如果已知:n1,n2,c1,c2,e1,e2,并且其中n1=n2的话:

s = egcd(e1, e2)
 s1 = s[1]
 s2 = s[2]
   print s
 n=n1
   if s1<0:
     s1 = - s1
     c1 = modinv(c1, n)
   elif s2<0:
     s2 = - s2
     c2 = modinv(c2, n)
 m=(pow(c1,s1,n)*pow(c2,s2,n)) % n

**0x06 总结 **

这里总结方法也不是全部的方法,但是希望能够对大家RSA方面解题过程中能提供一些帮助。这里推荐汪神的OJ系统,里面题目多多,关于RSA也有不少,可以在此练习:https://www.jarvisoj.com

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,324评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,303评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,192评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,555评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,569评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,566评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,927评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,583评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,827评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,590评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,669评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,365评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,941评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,928评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,159评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,880评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,399评论 2 342

推荐阅读更多精彩内容

  • RSA算法它是第一个既能用于数据加密也能用于数字签名的算法。它易于理解和操作,也很流行。算法的名字以发明者的名字命...
    火狼o阅读 640评论 0 1
  • RSA加密算法是最常用的非对称加密算法,CFCA在证书服务中离不了它。但是有不少新来的同事对它不太了解,恰好看到一...
    ikin阅读 2,077评论 0 5
  • 在生活中, 有时你会感到非常的累。 这种累别人无法体会, 自己也无法用言语表达。 只能是一个人默默的承受着! 那么...
    心春去梦秋来阅读 338评论 2 4
  • 忽然觉得自己做错啦,不是自己的事最好不要管,好心未必得到好报。事事如此,这可能就是事不关己,高高挂起。
    憧憬幸福阅读 195评论 0 0
  • 对于地中海来说,白色和蓝色是两个主打,最好还要有造型别致的拱廊和细细小小的石砾。在打造地中海风格的家居时,配色是一...
    笑笑_5e62阅读 444评论 0 0