Crypto之RSA(一)

最近在学习CTF中Crypto,整理一些关于RSA的知识点,以及在以往比赛中出现的题目。
完美的密码技术因为有不完美的人类参与而无法实现完美的安全性。

简单介绍RSA

RSA是1977年由 罗纳德·李维斯特(Ron Rivest)、阿迪·萨莫尔(Adi Shamir)和伦纳德·阿德曼 (Leonard Adleman)一起提出的。当时他们三人都在麻省理工学院工作。RSA就是他们三人姓氏开头字母拼在一起组成的,三个人名字要有印象,有些题目会用这三个名字,这样可以帮助我们快速判断题目。

RSA公开密钥密码体制的原理是:基于数论,我们能知道随便找两个大素数比较简单,但是如果给定两个大素数的乘积来进行因式分解是及其困难的,因此可以将乘积公开作为加密密钥。

即使 RSA 算法目前来说是安全可靠的,但是错误的应用场景,错误的环境配置,以及错误的使用方法都会导致 RSA 的算法体系出现问题,从而也诞生出针对各种特定场景下的 RSA 攻击方法

RSA公钥密码

RSA公钥密码体制描述如下:
1)选取两个大素数p和q,p和q保密
2)计算n=pq,φ(n)=(p-1)(q-1),n公开,φ(n)(欧拉函数值)保密
3)随机选取正整数 1<e<φ(n),满足gcd(e,φ(n)) = 1,e是公开的加密密钥
4)计算d,满足ed≡1(modφ(n)),d是保密的解密密钥

加密变换:c = m^e mod n
解密变换:m = c^d mod n

虽然n,e 是公开的,但是要想知道 d 的值,必须要将 n 分解来计算出 n 的欧拉函数值,而 n 是两个大素数 p,q 的积, 前面说过分解是及其困难的。 但是对于特定的情况可以使用特殊方法进行分解。
上文以及下文会涉及到一些具体的数论知识,例如:中国剩余定理,同余求余运算,欧拉函数等,大家可以自行查询或者通过《信息安全数学基础》或《现代密码学》进行自学,本文主要针对CTF比赛中关于RSA常见的题型讲解。

gmpy2

python中的一个数论库,本文一些题目的脚本几乎都是基于这个进行编写。可以自行查询。
安装方法pip install gmpy2

CTF中RSA题目常见类型

最最最简单

解决 RSA 题目最简单,最暴力,就是直接分解 n。如果能够将 n 分解成功,得到 p,q 的取值,那么可求φ(n). φ(n)=(p-1)(q-1)
利用e,d 与 n 的欧拉函数满足 ed≡1(modφ(n))
通过欧几里得算法可以通过 e 与 n 的欧拉函数值从而求出 d,计算出解密密钥。
所以在知道 e,p,q 的情况下,就可以解出 d(其实啥都给了,就让你代数计算了)

例题

p = 3487583947589437589237958723892346254777
q = 8767867843568934765983476584376578389
e = 65537 求d?

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

直接分解 n

素数分解问题是困难的,但是可以暴力分解。通常意义上来说,一般认为 2048bit 以上的 n 是安全的。现在一般的公钥证书都是 4096bit 的证书。
针对大整数的分解有很多种算法,性能上各有优异,有 Fermat 方法,Pollard rho 方法,试除法,以及椭圆曲线法,连分数法,二次筛选法,数域分析法等
推荐一个大整数素分解的网站http://www.factordb.com/
通过在网站上输入 n 的值,如果可以分解或者之前分解成功过,那么我们可以直接得到 p 和 q。然后利用前面方法求解得到密文

例题

2020-CSICTF-Crypto-little RSA
此题可以在CTF-hub上找到
题目包含一个flag.zip 有加密密码,一个enc.txt
ent.txt中的数据

c=32949
n=64741
e=42667

那么我们就可以利用网站将n分解然后使用脚本解密

import gmpy2
c = 32949
n = 64741
e = 42667
p = 101
q = 641
phi = (p - 1) * (q - 1)  # φ(n)
d = gmpy2.invert(e, phi)
a = pow(c, d, n)  # c的d次方 mod n
print(a)

输出a的结果18429 便是flag.zip的解压密码,然后解压后就是flag的文本文件
flagcsictf{gr34t_m1nds_th1nk_4l1ke}

利用公约数分解 n

如果在两次加密过程中使用的n1和n2具有相同的素因子,那么可以利用欧几里得算法直接将n1和n2分解。通过欧几里得算法可以直接求出n1和n2的一个最大公约数p:
gcd(n1,n2)=p
这样的话
q1 = n1 / p
q2 = n2 / p

例题

**2020-BJDCTF-Crypto-rsa **
因为题目已经提示了e=52361 那么我们先直接用
从题目附件的task,py提取所需数据

import gmpy2

c1 = 12641635617803746150332232646354596292707861480200207537199141183624438303757120570096741248020236666965755798009656547738616399025300123043766255518596149348930444599820675230046423373053051631932557230849083426859490183732303751744004874183062594856870318614289991675980063548316499486908923209627563871554875612702079100567018698992935818206109087568166097392314105717555482926141030505639571708876213167112187962584484065321545727594135175369233925922507794999607323536976824183162923385005669930403448853465141405846835919842908469787547341752365471892495204307644586161393228776042015534147913888338316244169120
n1 = 13508774104460209743306714034546704137247627344981133461801953479736017021401725818808462898375994767375627749494839671944543822403059978073813122441407612530658168942987820256786583006947001711749230193542370570950705530167921702835627122401475251039000775017381633900222474727396823708695063136246115652622259769634591309421761269548260984426148824641285010730983215377509255011298737827621611158032976420011662547854515610597955628898073569684158225678333474543920326532893446849808112837476684390030976472053905069855522297850688026960701186543428139843783907624317274796926248829543413464754127208843070331063037
c2 = 97915337055253515349847745972087732981120468820838754382612258213240421484845495472248708665806140879522380502220299761352201473698345
n2 = 12806210903061368369054309575159360374022344774547459345216907128193957592938071815865954073287532545947370671838372144806539753829484356064919357285623305209600680570975224639214396805124350862772159272362778768036844634760917612708721787320159318432456050806227784435091161119982613987303255995543165395426658059462110056431392517548717447898084915167661172362984251201688639469652283452307712821398857016487590794996544468826705600332208535201443322267298747117528882985955375246424812616478327182399461709978893464093245135530135430007842223389360212803439850867615121148050034887767584693608776323252233254261047
e = 52361
p = gmpy2.gcd(n1, n2)
q = n1 // p
phi = (p - 1) * (q - 1)

d = gmpy2.invert(e, phi)

flag = pow(c1, d, n1)

print(bytes.fromhex(hex(flag)[2:]))

最终flag为BJD{p_is_common_divisor}
当然e如果没有提示呢,e小于100000,又有pow(294,e,n),可以通过爆破e的取值很快得到e,代码如下

output=381631268825806469518166370387352035475775677163615730759454343913563615970881967332407709901235637718936184198930226303761876517101208677107311006065728014220477966000620964056616058676999878976943319063836649085085377577273214792371548775204594097887078898598463892440141577974544939268247818937936607013100808169758675042264568547764031628431414727922168580998494695800403043312406643527637667466318473669542326169218665366423043579003388486634167642663495896607282155808331902351188500197960905672207046579647052764579411814305689137519860880916467272056778641442758940135016400808740387144508156358067955215018
for i in range(100000):
	res=pow(294,i,n1)
	if (res==output):
		print(i)
		e=i
		break

共模攻击

如果使用了相同的模 n 对相同的明文 m 进行了加密,我们就可以在不分解 n 的情况下还原出明文 m 的值。即
c1 = m^e1 mod n
c2 = m^e2 mod n
此时不需要分解n,也不需要求解私钥,如果e1和e2互素,那么就可以利用共模攻击利用两个密文和公钥给出的情况下还原密文m

简单的过程,前提条件两个加密指数互质
gcd(e1,e2) = 1,那么s2存在,则:
s1 * e1 + s2 * e2 = 1
因为c1 = m^e1 mod n,c2 = m^e2 mod n
代入化简可以得出 c1^s2 * c2^s2 ≡ m mod n

例题

2020-第五空间智能安全大赛-Crypto-rosb
根据题目给出的py文件,提取所需参数,写出脚本

import gmpy2

n = 0xa1d4d377001f1b8d5b2740514ce699b49dc8a02f12df9a960e80e2a6ee13b7a97d9f508721e3dd7a6842c24ab25ab87d1132358de7c6c4cee3fb3ec9b7fd873626bd0251d16912de1f0f1a2bba52b082339113ad1a262121db31db9ee1bf9f26023182acce8f84612bfeb075803cf610f27b7b16147f7d29cc3fd463df7ea31ca860d59aae5506479c76206603de54044e7b778e21082c4c4da795d39dc2b9c0589e577a773133c89fa8e3a4bd047b8e7d6da0d9a0d8a3c1a3607ce983deb350e1c649725cccb0e9d756fc3107dd4352aa18c45a65bab7772a4c5aef7020a1e67e6085cc125d9fc042d96489a08d885f448ece8f7f254067dfff0c4e72a63557
e1 = 0xf4c1158f
c1 = 0x2f6546062ff19fe6a3155d76ef90410a3cbc07fef5dff8d3d5964174dfcaf9daa003967a29c516657044e87c1cbbf2dba2e158452ca8b7adba5e635915d2925ac4f76312feb3b0c85c3b8722c0e4aedeaec2f2037cc5f676f99b7260c3f83ffbaba86cda0f6a9cd4c70b37296e8f36c3ceaae15b5bf0b290119592ff03427b80055f08c394e5aa6c45bd634c80c59a9f70a92dc70eebec15d4a5e256bf78775e0d3d14f3a0103d9ad8ea6257a0384091f14da59e52581ba2e8ad3adb9747435e9283e8064de21ac41ab2c7b161a3c072b7841d4a594a8b348a923d4cc39f02e05ce95a69c7500c29f6bb415c11e4e0cdb410d0ec2644d6243db38e893c8a3707
e2 = 0xf493f7d1
c2 = 0xd32dfad68d790022758d155f2d8bf46bb762ae5cc17281f2f3a8794575ec684819690b22106c1cdaea06abaf7d0dbf841ebd152be51528338d1da8a78f666e0da85367ee8c1e6addbf590fc15f1b2182972dcbe4bbe8ad359b7d15febd5597f5a87fa4c6c51ac4021af60aeb726a3dc7689daed70144db57d1913a4dc29a2b2ec34c99c507d0856d6bf5d5d01ee514d47c7477a7fb8a6747337e7caf2d6537183c20e14c7b79380d9f7bcd7cda9e3bfb00c2b57822663c9a5a24927bceec316c8ffc59ab3bfc19f364033da038a4fb3ecef3b4cb299f4b600f76b8a518b25b576f745412fe53d229e77e68380397eee6ffbc36f6cc734815cd4065dc73dcbcb

s = gmpy2.gcdext(int(e1), int(e2))  # 扩展欧几里得算法

s1 = s[1]
s2 = s[2]

# 求模反元素
if s1 < 0:
    s1 = -s1
    c1 = gmpy2.invert(c1, n)

elif s2 < 0:
    s2 = -s2
    c2 = gmpy2.invert(c2, n)

m = pow(c1, s1, n) * pow(c2, s2, n) % n

print(bytes.fromhex(hex(m)[2:]))

flagg0od_go0d_stu4y_d4yd4y_Up

以上是RSA简单入门,当然常见类型还有低加密指数攻击,低解密指数攻,Coppersmith 相关攻击,侧信道,选择明密文攻击等等,我们会在后续文章逐步补充并且会再多整理几道CTF出现过的例题。

es.fromhex(hex(m)[2:]))

flag`g0od_go0d_stu4y_d4yd4y_Up`

以上是RSA简单入门,当然常见类型还有低加密指数攻击,低解密指数攻,Coppersmith 相关攻击,侧信道,选择明密文攻击等等,我们会在后续文章逐步补充并且会再多整理几道CTF出现过的例题。

  • 5
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: buuctf crypto rsarsa 是一个密码学竞赛中的题目,涉及到 RSA 加密算法。RSA 是一种非对称加密算法,常用于数据加密和数字签名。在该题目中,可能需要对 RSA 加密算法的原理和实现进行深入的研究和分析,以解决加密和解密的问题。 ### 回答2: BUUCTF是一个针对计算机安全领域的技能竞赛,旨在提高选手的安全防护意识和技术能力。其中涉及的加密算法RSA在密码学中属于非对称加密算法,其加密过程中需要用到两个密钥,一个是公钥,一个是私钥。在加密过程中,公钥用于加密明文,而私钥则用于解密密文。因此,RSA算法的安全性取决于私钥的保护,若私钥泄漏,则加密数据不再安全。 在BUUCTF的RSA题目中,选手需要利用给定的RSA公钥、密文等信息来解密出原始明文。首先,选手需要对给定的公钥进行分解,以求出两个大质数p和q,并计算出n=p*q。然后选手需要求出一个整数e,使得e与(p-1)*(q-1)互质。选手需要利用扩展欧几里得算法求出一个整数d,使得d*e mod (p-1)*(q-1)=1。最后,选手就可以利用求得的d,将密文解密为原始明文。 在针对RSA算法的攻击方法中,通过枚举计算或利用数学上的漏洞,攻击者可以猜测出素数p和q的值,推导出解密私钥,并进一步利用私钥进行加密和签名等操作,从而窃取数据和获得系统控制权。因此,选手需要具备RSA算法的基本理论知识和常用攻击方法,并掌握实际应用中的RSA加密、解密及签名等操作。只有建立起一个扎实的RSA算法基础,才能在BUUCTF竞赛中成功击败其他选手。 ### 回答3: buuctf crypto rsarsa是一个密码学竞赛中的一个题目,旨在测试参赛者对于RSA算法的理解和应用能力。 RSA算法是目前最为常用的公钥加密算法之一,它的安全性基于质因数分解问题。在加密时,通过选择两个足够大的质数p和q,将它们相乘得到一个大的合数n,然后选择一个整数e作为公开密钥,满足e和(p-1)(q-1)互质。接着,选取一个整数d作为私有密钥,使得e*d mod (p-1)(q-1) = 1。然后,任何人都可以通过公开密钥(e,n)将明文m进行加密,得到密文c = m^e mod n。而只有知道私有密钥(d,n)的人才能够将密文c进行解密,得到明文m = c^d mod n。 在这道buuctf crypto rsarsa题目中,我们需要破解一个RSA加密过的密文,得到原始明文。题目给出了一个密文c和公钥(e,n),但是并没有给出私钥d。首先,我们需要对n进行质因数分解,求出p和q。这里我们可以使用Pollard-Rho算法或是其他的质因数分解算法。一旦我们求出了p和q,我们就能够计算出(p-1)(q-1),并通过扩展欧几里得算法求出私钥d。然后,我们就可以使用私钥d来解密密文得到明文了。 需要注意的是,在实际应用中,RSA算法需要保证选择的质数p和q足够大,才能够抵御当前已知的攻击手段。同时,在实现中还需要注意一些常见的安全漏洞,例如使用相同的公开指数e等。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值