CTFshow-Crypto(26-29)

26easyrsa6

分解n/费马分解

import gmpy2,libnum
from Crypto.Util.number import getPrime

e = 0x10001
p = getPrime(1024)
q = gmpy2.next_prime(p)
n = p * q
print("n =",n)
m = libnum.s2n(flag)
c = pow(m,e,n)
print("c =", c)

# n = 26737417831000820542131903300607349805884383394154602685589253691058592906354935906805134188533804962897170211026684453428204518730064406526279112572388086653330354347467824800159214965211971007509161988095657918569122896402683130342348264873834798355125176339737540844380018932257326719850776549178097196650971801959829891897782953799819540258181186971887122329746532348310216818846497644520553218363336194855498009339838369114649453618101321999347367800581959933596734457081762378746706371599215668686459906553007018812297658015353803626409606707460210905216362646940355737679889912399014237502529373804288304270563
# c = 18343406988553647441155363755415469675162952205929092244387144604220598930987120971635625205531679665588524624774972379282080365368504475385813836796957675346369136362299791881988434459126442243685599469468046961707420163849755187402196540739689823324440860766040276525600017446640429559755587590377841083082073283783044180553080312093936655426279610008234238497453986740658015049273023492032325305925499263982266317509342604959809805578180715819784421086649380350482836529047761222588878122181300629226379468397199620669975860711741390226214613560571952382040172091951384219283820044879575505273602318856695503917257

看到e=0x10001

16进制转为10进制是65537

image-20240604153749146

分解nhttp://www.factordb.com/

image-20240604154302228

我们注意到

p = getPrime(1024)
q = gmpy2.next_prime(p)

p q相差太小 所以 n=p*q ≈p²,费马分解

p = gmpy2.next_prime(gmpy2.iroot(n,2)[0])
q = n//p
脚本
import gmpy2,libnum
from Crypto.Util.number import *

\# e = 0x10001
\# p = getPrime(1024)
\# q = gmpy2.next_prime(p)
\# n = p * q
\# print("n =",n)
\# m = libnum.s2n(flag)
\# c = pow(m,e,n)
\# print("c =", c)

n = 26737417831000820542131903300607349805884383394154602685589253691058592906354935906805134188533804962897170211026684453428204518730064406526279112572388086653330354347467824800159214965211971007509161988095657918569122896402683130342348264873834798355125176339737540844380018932257326719850776549178097196650971801959829891897782953799819540258181186971887122329746532348310216818846497644520553218363336194855498009339838369114649453618101321999347367800581959933596734457081762378746706371599215668686459906553007018812297658015353803626409606707460210905216362646940355737679889912399014237502529373804288304270563
c = 18343406988553647441155363755415469675162952205929092244387144604220598930987120971635625205531679665588524624774972379282080365368504475385813836796957675346369136362299791881988434459126442243685599469468046961707420163849755187402196540739689823324440860766040276525600017446640429559755587590377841083082073283783044180553080312093936655426279610008234238497453986740658015049273023492032325305925499263982266317509342604959809805578180715819784421086649380350482836529047761222588878122181300629226379468397199620669975860711741390226214613560571952382040172091951384219283820044879575505273602318856695503917257
p = 163515803000813412334620775647541652549604895368507102613553057136855632963322853570924931001138446030409251690646645635800254129997200577719209532684847732809399187385176309169421205833279943214621695444496660249881675974141488357432373412184140130503562295159152949524373214358417567189638680209172147385163
q = 163515803000813412334620775647541652549604895368507102613553057136855632963322853570924931001138446030409251690646645635800254129997200577719209532684847732809399187385176309169421205833279943214621695444496660249881675974141488357432373412184140130503562295159152949524373214358417567189638680209172147385801
e = 65537
phi = (p-1)*(q-1)
d = gmpy2.invert(e,phi)
m = pow(c,d,n)
print(long_to_bytes(m))
工具(风二西)

image-20240604155218484

27easyrsa7

CopperSmith攻击 低位数据缺失-知p高位

RSA中coppersmith定理的应用条件_sagemath coppersmith-CSDN博客

e = 0x10001
p>>128<<128 = 0xd1c520d9798f811e87f4ff406941958bab8fc24b19a32c3ad89b0b73258ed3541e9ca696fd98ce15255264c39ae8c6e8db5ee89993fa44459410d30a0a8af700ae3aee8a9a1d6094f8c757d3b79a8d1147e85be34fb260a970a52826c0a92b46cefb5dfaf2b5a31edf867f8d34d2222900000000000000000000000000000000
n = 0x79e0bf9b916e59286163a1006f8cefd4c1b080387a6ddb98a3f3984569a4ebb48b22ac36dff7c98e4ebb90ffdd9c07f53a20946f57634fb01f4489fcfc8e402865e152820f3e2989d4f0b5ef1fb366f212e238881ea1da017f754d7840fc38236edba144674464b661d36cdaf52d1e5e7c3c21770c5461a7c1bc2db712a61d992ebc407738fc095cd8b6b64e7e532187b11bf78a8d3ddf52da6f6a67c7e88bef5563cac1e5ce115f3282d5ff9db02278859f63049d1b934d918f46353fea1651d96b2ddd874ec8f1e4b9d487d8849896d1c21fb64029f0d6f47e560555b009b96bfd558228929a6cdf3fb6d47a956829fb1e638fcc1bdfad4ec2c3590dea1ed3
c = 0x1b2b4f9afed5fb5f9876757e959c183c2381ca73514b1918d2f123e386bebe9832835350f17ac439ac570c9b2738f924ef49afea02922981fad702012d69ea3a3c7d1fc8efc80e541ca2622d7741090b9ccd590906ac273ffcc66a7b8c0d48b7d62d6cd6dd4cd75747c55aac28f8be3249eb255d8750482ebf492692121ab4b27b275a0f69b15baef20bf812f3cbf581786128b51694331be76f80d6fb1314d8b280eaa16c767821b9c2ba05dfde5451feef22ac3cb3dfbc88bc1501765506f0c05045184292a75c475486b680f726f44ef8ddfe3c48f75bb03c8d44198ac70e6b7c885f53000654db22c8cee8eb4f65eaeea2da13887aaf53d8c254d2945691

新题型

>> 和 <<都是位运算,对二进制数进行移位操作

>> 1 右移一位 相当于 /2

这里 “p>>128<<128" p右移128位再左移128位 之后 p末尾很多0,p低位数据缺失

p,q二进制位数相同时 β一般只能取 0.4

利用 sagemath 去恢复p

下载使用

【SageMath】SageMath在Windows系统下的安装_sagemath下载-CSDN博客

SageMath的新手保姆使用教程-CSDN博客

安装第三方库

在sagemath中安装第三方库_pip install sage-CSDN博客

#sage#
p = 0xd1c520d9798f811e87f4ff406941958bab8fc24b19a32c3ad89b0b73258ed3541e9ca696fd98ce15255264c39ae8c6e8db5ee89993fa44459410d30a0a8af700ae3aee8a9a1d6094f8c757d3b79a8d1147e85be34fb260a970a52826c0a92b46cefb5dfaf2b5a31edf867f8d34d2222900000000000000000000000000000000
n = 0x79e0bf9b916e59286163a1006f8cefd4c1b080387a6ddb98a3f3984569a4ebb48b22ac36dff7c98e4ebb90ffdd9c07f53a20946f57634fb01f4489fcfc8e402865e152820f3e2989d4f0b5ef1fb366f212e238881ea1da017f754d7840fc38236edba144674464b661d36cdaf52d1e5e7c3c21770c5461a7c1bc2db712a61d992ebc407738fc095cd8b6b64e7e532187b11bf78a8d3ddf52da6f6a67c7e88bef5563cac1e5ce115f3282d5ff9db02278859f63049d1b934d918f46353fea1651d96b2ddd874ec8f1e4b9d487d8849896d1c21fb64029f0d6f47e560555b009b96bfd558228929a6cdf3fb6d47a956829fb1e638fcc1bdfad4ec2c3590dea1ed3

pbits = 1024
kbits = 128
#pbits 和 kbits: 分别表示 p 和一个中间步骤中的某些数值的位数。
PR.<x> = PolynomialRing(Zmod(n))
#Zmod(n):指定模,定义界限为n的环;Z表示整数;指定模是划定这个环的界限,就是有效的数字只有从0到n,其他的都通过与n取模来保证在0~n这个范围内;Zmod代表这是一个整数域中的n模环
#ZZ:整数环;QQ:有理数环;RR:实数环;CC:复数环
#R:只是一个指针,指向用polynomialring指定的那个环(可以使用任意字符)
#PolynomialRing:这个就是说建立多项式环
#.<X>:指定一个变量的意思(可以用任意字符)
f = x + p
#定义了一个多项式 f(x) = x + p。
roots = f.small_roots(X=2^kbits, beta=0.4)
#small_roots 方法试图找到多项式的根,这些根在 [0, X) 范围内,并且满足一定的“小”条件(由 beta 参数控制)。具体来说,X 是我们想要查找的根的最大值(这里是 2^kbits),而 beta 是一个浮点数,用于控制算法的复杂性。通常,beta 的值越大,算法会更快,但可能找到的根越少。
if roots:
	p = p+int(roots[0])
	print("p = "+str(p))
#如果 small_roots 方法找到了根(即 roots 非空),那么代码将 p 更新为 p 加上找到的第一个根,并打印出新的 p 值。

image-20240604212225496

from Crypto.Util.number import *
from gmpy2 import *

e = 0x10001
n = 0x79e0bf9b916e59286163a1006f8cefd4c1b080387a6ddb98a3f3984569a4ebb48b22ac36dff7c98e4ebb90ffdd9c07f53a20946f57634fb01f4489fcfc8e402865e152820f3e2989d4f0b5ef1fb366f212e238881ea1da017f754d7840fc38236edba144674464b661d36cdaf52d1e5e7c3c21770c5461a7c1bc2db712a61d992ebc407738fc095cd8b6b64e7e532187b11bf78a8d3ddf52da6f6a67c7e88bef5563cac1e5ce115f3282d5ff9db02278859f63049d1b934d918f46353fea1651d96b2ddd874ec8f1e4b9d487d8849896d1c21fb64029f0d6f47e560555b009b96bfd558228929a6cdf3fb6d47a956829fb1e638fcc1bdfad4ec2c3590dea1ed3
p = 147305526294483975294006704928271118039370615054437206404408410848858740256154476278591035455064149531353089038270283281541411458250950936656537283482331598521457077465891874559349872035197398406708610440618635013091489698011474611145014167945729411970665381793142591665313979405475889978830728651549052207969
q = n // p
c = 0x1b2b4f9afed5fb5f9876757e959c183c2381ca73514b1918d2f123e386bebe9832835350f17ac439ac570c9b2738f924ef49afea02922981fad702012d69ea3a3c7d1fc8efc80e541ca2622d7741090b9ccd590906ac273ffcc66a7b8c0d48b7d62d6cd6dd4cd75747c55aac28f8be3249eb255d8750482ebf492692121ab4b27b275a0f69b15baef20bf812f3cbf581786128b51694331be76f80d6fb1314d8b280eaa16c767821b9c2ba05dfde5451feef22ac3cb3dfbc88bc1501765506f0c05045184292a75c475486b680f726f44ef8ddfe3c48f75bb03c8d44198ac70e6b7c885f53000654db22c8cee8eb4f65eaeea2da13887aaf53d8c254d2945691

phi_n = (p - 1) * (q - 1)

d = invert(e, phi_n)
m = pow(c, d, n)
print(long_to_bytes(m))

28easyrsa8

公钥解析

下载附件是两个文件

image-20240604163602251

将public.key文件内容进行公钥解析得到e和n

SSL在线工具-公钥解析 (hiencode.com)

image-20240604164251074

分解n

n=10306247299477991196335954707897189353577589618180446614762218980226685668311143526740800444344046158260556585833057716406703213966249956775927205061731821632025483608182881492214855240841820024816859031176291364212054293818204399157346955465232586109199762630150640804366966946066155685218609638749171632685073
e=65537
p=97
q=106249972159566919549855203174197828387397831115262336234662051342543151219702510584956705611794290291345944183845955839244363030579896461607496959399297130227066841321473005074379950936513608503266587950271044991876848389878395867601515004796212227929894460104645781488319246866661398816686697306692491058609

密文c就是flag.enc

使用RSA算法加密字符串:从基础到实现 - Python-CSDN博客

脚本

import gmpy2
from Crypto.Cipher import PKCS1_OAEP
\# PKCS1 OAEP 是一种基于 RSA 和 OAEP 填充的非对称密码
\#用于RSA的OAEP填充解密。
from Crypto.PublicKey import RSA
\#用于RSA公钥和私钥的生成和操作。

n=10306247299477991196335954707897189353577589618180446614762218980226685668311143526740800444344046158260556585833057716406703213966249956775927205061731821632025483608182881492214855240841820024816859031176291364212054293818204399157346955465232586109199762630150640804366966946066155685218609638749171632685073
e=65537
p=97
q=106249972159566919549855203174197828387397831115262336234662051342543151219702510584956705611794290291345944183845955839244363030579896461607496959399297130227066841321473005074379950936513608503266587950271044991876848389878395867601515004796212227929894460104645781488319246866661398816686697306692491058609

phi_n = (p - 1) * (q - 1)
d = int(gmpy2.invert(e, phi_n))

\#rsakey = RSA.importKey(open(r"C:\Users\86157\Desktop\easyrsa8\public.key", 'r').read())
\#从文件中导入公钥,但是已经有了私钥的所有参数,所以不需要从文件中导入公钥。
privatekey = RSA.construct((n, e, d, p, q))
\#构造私钥
rsa = PKCS1_OAEP.new(privatekey)
\#使用私钥和PKCS1_OAEP填充来初始化解密器。
m = rsa.decrypt(open(r"C:\Users\86157\Desktop\easyrsa8\flag.enc", 'rb').read())
\#读取加密的文件,并使用之前初始化的解密器来解密。
print(m)

29funnyrsa1

两个e c q不同,p相同(e与phi不互素)+CRT

e1 = 14606334023791426
p1 = 121009772735460235364940622989433807619211926015494087453674747614331295040063679722422298286549493698150690694965106103822315378461970129912436074962111424616439032849788953648286506433464358834178903821069564798378666159882090757625817745990230736982709059859613843100974349380542982235135982530318438330859
q1 = 130968576816900149996914427770826228884925960001279609559095138835900329492765336419489982304805369724685145941218640504262821549441728192761733409684831633194346504685627189375724517070780334885673563409259345291959439026700006694655545512308390416859315892447092639503318475587220630455745460309886030186593
c1 = 11402389955595766056824801105373550411371729054679429421548608725777586555536302409478824585455648944737304660137306241012321255955693234304201530700362069004620531537922710568821152217381257446478619320278993539785699090234418603086426252498046106436360959622415398647198014716351359752734123844386459925553497427680448633869522591650121047156082228109421246662020164222925272078687550896012363926358633323439494967417041681357707006545728719651494384317497942177993032739778398001952201667284323691607312819796036779374423837576479275454953999865750584684592993292347483309178232523897058253412878901324740104919248

e2 = 13813369129257838
p2 = 121009772735460235364940622989433807619211926015494087453674747614331295040063679722422298286549493698150690694965106103822315378461970129912436074962111424616439032849788953648286506433464358834178903821069564798378666159882090757625817745990230736982709059859613843100974349380542982235135982530318438330859
q2 = 94582257784130735233174402362819395926641026753071039760251190444144495369829487705195913337502962816079184062352678128843179586054535283861793827497892600954650126991213176547276006780610945133603745974181504975165082485845571788686928859549252522952174376071500707863379238688200493621993937563296490615649
c2 = 7984888899827615209197324489527982755561403577403539988687419233579203660429542197972867526015619223510964699107198708420785278262082902359114040327940253582108364104049849773108799812000586446829979564395322118616382603675257162995702363051699403525169767736410365076696890117813211614468971386159587698853722658492385717150691206731593509168262529568464496911821756352254486299361607604338523750318977620039669792468240086472218586697386948479265417452517073901655900118259488507311321060895347770921790483894095085039802955700146474474606794444308825840221205073230671387989412399673375520605000270180367035526919

给定两个密文(c1 c2)的情况下,通常需要找到两者之间存在的关系,“合并”密文求解才能得到正确的明文。

先计算phi1和phi2,然后分别计算e和phi的gcd,发现都等于14,所以这里问题考察e和phi不互素(d的逆元求不出来)情况下的求解。

由于m^e mod n =c,m一样,e不同,c才不同。改变了e,对应的密文c也需要改变

image-20240604184938552

我们把 m^14看成一个整体 M 则 M^x ≡ c mod n 那么 M的加密指数E 就是x,解密指数D就变成了 invert(x,phi) 从而我们就可以根据 c^D = M mod n 求解出来M 即(m^x ),对M开x次方根即可得到m

但根据第一段已知条件就能把m求出来吗?显然是不可能的。两段已知条件中p1和p2是相等的,但是q1和q2不相等,所以p1*q1!=p2*q2,也就是说两段条件下m所在的有限域不同,第一段条件直接开根解出来的明文m不一定满足第二段的域

不可以直接利用其中一段已知 e、p、q、c求出来m

正确思路:

已知存在如下数学公等式:

1  gcd(e,phi)=b

2  e = a * b

3  e*d ≡ 1 mod phi

4  m^e ≡ c mod n

5  a*b*d ≡ 1 mod phi 由2和3得到,这里可以推出a*b*d mod phi = 1

6  m^(a*b) ≡ c mod n 由2和4得到,这里可以变换成c ≡ m^(a*b) mod n

存在性质:

image-20240604190739805

由以上可以推出c^(b*d) ≡ m^(abbd) mod n

因为a*b*d=1

所以c^(bd) ≡ m^b mod n

所以我们先要求出b*d,然后就能算出m^b。求bd我们可以根据5式子,所以要算出a。由题目分析我们知道b=14,所以a=e/b。代码如下:

p = p1
phi1 = (p - 1) * (q1 - 1)
phi2 = (p - 1) * (q2 - 1)
b = gmpy2.gcd(e1, phi1)
a1 = e1 // b
a2 = e2 // b
bd1 = gmpy2.invert(a1, phi1)
bd2 = gmpy2.invert(a2, phi2)

由以上我们分别求出了bd,然后就可以分别算出mb。到了这一步还是无法算出m的(因为两段已知条件中p1和p2是相等的,但是q1和q2不相等,所以p1*q1!=p2*q2,也就是说两段条件下m所在的有限域不同,第一段条件直接开根解出来的明文m不一定满足第二段的域)

有同余式组:

c1 ≡ m^b1 mod n1  变换得到  c1 ≡ m^b1 mod (p1 * q1) 
c2 ≡ m^b2 mod n2    同理 c2 ≡ m^b2 mod (p2 * q2)

根据同余性质:
$$
a ≡ b mod (mn) 则 a ≡ b mod m,a ≡ b mod n
$$
所以得到下列式子:

c1 ≡ m^b1 mod p1

c1 ≡ m^b1 mod q1

c2 ≡ m^b2 mod p2

c2 ≡ m^b2 mod q2

因为p1和p2相等,则c1 ≡ m^b1 mod p,c2 ≡ m^b2 mod p

根据如下性质:

image-20240604192104907

我们可以得到c3 ≡(m^b1 * m^b2 )mod p

代码如下:

mb1 = pow(c1, bd1, n1)
mb2 = pow(c2, bd2, n2)
c3 = mb1 * mb2 % p
c2 = mb2 % q2
c1 = mb1 % q1

根据中国剩余定理

image-20240604192436147

简单来说,就是求一个整数满足一组同余式组。

所以这里把c1,c2,c3 "连接" 起来,求一个特解c,即c满足如下:

c3 = c % p

c2 = c % q2

c1 = c % q1

所以求特解c的代码如下:

res = solve_crt([c1, c2, c3], [q1, q2, p]) 
libnum库 solve_crt 专门求解中国剩余定理特解
第一个列表是各个同余方程右侧的常数(即余数)
第二个列表是各个同余方程右侧的模数(即除数)
函数返回一个整数解,该解满足给定的同余方程组

于是我们重新得到了c ≡ m^e mod n的形式:

res ≡ m^14 mod q1*q2

e依旧是14,n=q1*q2

m^14 = c mod q1*q2 这里依旧不能直接开方求(此时 14 与 phi_n 不互素,求不出d )

gcd(e,phi_n)=2

因此 把 (m^2)^7 = c mod q1*q2 这里把 m^2看成整体,求D = invert(7,(q1-1)*(q2-1)) 之后rsa 根据 c^D = M mod n

得到 m^2 开二次根得到明文m

image-20240604192904902

代码如下:

n = q1 * q2
f = (q1 - 1) * (q2 - 1)
m = res % n
d2 = gmpy2.invert(7, f)
m = pow(m, d2, n)
msg = gmpy2.iroot(m, 2)[0]
print(long_to_bytes(msg))

完整代码:

from Crypto.Util.number import *
import gmpy2
from libnum import *

e1 = 14606334023791426
p1 = 121009772735460235364940622989433807619211926015494087453674747614331295040063679722422298286549493698150690694965106103822315378461970129912436074962111424616439032849788953648286506433464358834178903821069564798378666159882090757625817745990230736982709059859613843100974349380542982235135982530318438330859
q1 = 130968576816900149996914427770826228884925960001279609559095138835900329492765336419489982304805369724685145941218640504262821549441728192761733409684831633194346504685627189375724517070780334885673563409259345291959439026700006694655545512308390416859315892447092639503318475587220630455745460309886030186593
c1 = 11402389955595766056824801105373550411371729054679429421548608725777586555536302409478824585455648944737304660137306241012321255955693234304201530700362069004620531537922710568821152217381257446478619320278993539785699090234418603086426252498046106436360959622415398647198014716351359752734123844386459925553497427680448633869522591650121047156082228109421246662020164222925272078687550896012363926358633323439494967417041681357707006545728719651494384317497942177993032739778398001952201667284323691607312819796036779374423837576479275454953999865750584684592993292347483309178232523897058253412878901324740104919248
n1 = p1 * q1

e2 = 13813369129257838
p2 = 121009772735460235364940622989433807619211926015494087453674747614331295040063679722422298286549493698150690694965106103822315378461970129912436074962111424616439032849788953648286506433464358834178903821069564798378666159882090757625817745990230736982709059859613843100974349380542982235135982530318438330859
q2 = 94582257784130735233174402362819395926641026753071039760251190444144495369829487705195913337502962816079184062352678128843179586054535283861793827497892600954650126991213176547276006780610945133603745974181504975165082485845571788686928859549252522952174376071500707863379238688200493621993937563296490615649
c2 = 7984888899827615209197324489527982755561403577403539988687419233579203660429542197972867526015619223510964699107198708420785278262082902359114040327940253582108364104049849773108799812000586446829979564395322118616382603675257162995702363051699403525169767736410365076696890117813211614468971386159587698853722658492385717150691206731593509168262529568464496911821756352254486299361607604338523750318977620039669792468240086472218586697386948479265417452517073901655900118259488507311321060895347770921790483894095085039802955700146474474606794444308825840221205073230671387989412399673375520605000270180367035526919
n2 = p2 * q2

p = p1
phi1 = (p - 1) * (q1 - 1)
phi2 = (p - 1) * (q2 - 1)
b = gmpy2.gcd(e1, phi1)
a1 = e1 // b
a2 = e2 // b
bd1 = gmpy2.invert(a1, phi1)
bd2 = gmpy2.invert(a2, phi2)

mb1 = pow(c1, bd1, n1)
mb2 = pow(c2, bd2, n2)
c3 = mb1 * mb2 % p
c2 = mb2 % q2
c1 = mb1 % q1

res = solve_crt([c1, c2, c3], [q1, q2, p])   #crt中国同余定理,求出特解作为
print(res)

n = q1 * q2
f = (q1 - 1) * (q2 - 1)
M = res % n
D = gmpy2.invert(7, f)
msg = pow(M, D, n)
m = gmpy2.iroot(msg, 2)[0]
print(long_to_bytes(m))
#flag{gcd_e&\xcf\x86_isn't_1}
#中间的\xcf\x86为utf-8编码,转换得到字符:φ
#flag{gcd_e&φ_isn't_1}
posted @ 2024-06-05 00:01  machacha  阅读(98)  评论(0编辑  收藏  举报