2021年9月绿城杯,CRYPTO的RSA-2

51 篇文章 8 订阅

2021年9月绿城杯,CRYPTO的RSA-2

在这里插入图片描述
.
.
打开文件,发现是分成两段的RSA加密,第一段加密flag[:20],第二段加密flag[20:]

from Crypto.Util.number import *
import gmpy2
from flag import flag
assert flag[:5]==b'flag{'

m1 = bytes_to_long(flag[:20])
p  = getPrime(512)
p1 = gmpy2.next_prime(p)
q  = getPrime(512)
q1 = gmpy2.next_prime(q)
n1 = p*q*p1*q1
print('n1 =',n1)
e = 0x10001
c1 = pow(m1,e,n1)
print('c1 =',c1)


m2 = bytes_to_long(flag[20:])
p2 = getPrime(1024)
q2 = getPrime(1024)
print('p2+q2 =',p2+q2)
print('q2*q2 =',p2*q2)
n2 = p2*p2*q2*q2*q2
print('n2 =',n2)
c2 = pow(m2,e,n2)
print('c2 =',c2)

#n1 = 6348779979606280884589422188738902470575876294643492831465947360363568026280963989291591157710389629216109615274754718329987990551836115660879103234129921943824061416396264358110216047994331119920503431491509529604742468032906950984256964560405062345280120526771439940278606226153077959057882262745273394986607004406770035459301695806378598890589432538916219821477777021460189140081521779103226953544426441823244765828342973086422949017937701261348963541035128661464068769033772390320426795044617751909787914185985911277628404632533530390761257251552073493697518547350246993679844132297414094727147161169548160586911
#c1 = 6201882078995455673376327652982610102807874783073703018551044780440620679217833227711395689114659144506630609087600915116940111002026241056808189658969089532597757995423694966667948250438579639890580690392400661711864264184444018345499567505424672090632235109624193289954785503512742400960515331371813467034511130432319427185134018830006918682733848618201088649690422818940385123599468595766345668931882249779415788129316594083269412221804774856038796248038700275509397599351533280014908894068141056694660319816046357462684688942519849441237878018480036145051967731081582598773076490918572392784684372694103015244826

#p2+q2 = 274773146761138462708137582309097386437793891793691383033856524303010811294101933454824485010521468914846151819876043508541879637544444256520741418495479393777132830985856522008561088410862815913292288683761657919121930016956916865849261153721097671315883469348972925757078089715102032241818526925988645578778
#q2*q2 = 18514724270030962172566965941723224386374076294232652258701085781018776172843355920566035157331579524980108190739141959926523082142273672741849552475156278397131571360099018592018959785627785130126477982765210498547680367230723634424036009539347854344573537848628061468892166199866227984167843139793429682559241317072979374002912607549039431398267184818771503468116379618249319324788996321340764624593443106354104274472601170229835219638093242557547840060892527576940077162990069687019966946826210112318408269749294366586682732614372434218768720577917368726530200897558912687470088583774711767599580037663378929000217
#n2 = 40588227045595304080360385041082238507044292731344465815296032905633525556943787610712651675460810768762763493579129831271018141591546207557410817432455139315527674932933085299277599173971912445226532235814580879585317211349524406424200622675880992390782025158621241499693400288031658194434641718026910652327933253877313106112861283314274635124734817398465059373562194694957841264834312640926278890386089611103714990646541470577351599526904458342660444968591197606820361364761648205241041444681145820799054413179462285509661124362074093583494932706249461954240408827087015525507173082129412234486228092002841868365895837463699200959915782767657258729794037776401995309244941171415842403617486719492483671490834562579225506831496881542530519595438932482796867853234159664409420977526102480385193101883785161080269573707156626838551506024455480650224305894501968583442346807126920740779780593650871645915149689424292912611578291912721896864772950410266629045542480009266574096080138709683466489568290569363478444349563498507530805502511051165160827192795520182720802422213364247355775222858214648603034743679187470844212529134374975737510982287957316878179964602394749601431823167982157434890459245394370728942790117156485268116758052636794417268680901420193002289035538753620555488506926366624641291881353268617130968991258983002165300186971963661666476600998389048880565199317280428349802824448329898502788492233381873026217202981921654673840142095839603360666049476100561268336225902504932800605464136192275593886736746497955270280541423593
#c2 = 25591090168544821761746024178724660839590948190451329227481168576490717242294520739865602061082558759751196452117720647426598261568572440942370039702932821941366792140173428488344932203576334292648255551171274828821657097667106792872200082579319963310503721435500623146012954474613150848083425126987554594651797477741828655238243550266972216752593788734836373144363217639612492397228808215205862281278774096317615918854403992620720969173788151215489908812749179861803144937169587452008097008940710091361183942268245271154461872102813602754439939747566507116519362821255724179093051041994730856401493996771276172343313045755916751082693149885922105491818225012844519264933137622929024918619477538521533548551789739698933067212305578480416163609137189891797209277557411169643568540392303036719952140554435338851671440952865151077383220305295001632816442144022437763089133141886924265774247290306669825085862351732336395617276100374237159580759999593028756939354840677333467281632435767033150052439262501059299035212928041546259933118564251119588970009016873855478556588250138969938599988198494567241172399453741709840486953189764289118312870580993115636710724139809708256360212728127786394411676427828431569046279687481368215137561500777480380501551616577832499521295655237360184159889151837766353116185320317774645294201044772828099074917077896631909654671612557207653830344897644115936322128351494551004652981550758791285434809816872381900401440743578104582305215488888563166054568802145921399726673752722820646807494657299104190123945675647

.
.
(这里积累第一个经验)
先看第一段,gmpy2.next_prime(p)函数的意思是取邻近p的下一个素数,那么很明显p和p1q和q1都是两两相邻的素数,相差很小,n12048bit级别的,没法硬钢。

后半段的n2和前半段的加密逻辑差别很大,所以不是两个n的模不互素。也不是像上一道题RSA1一样的密文与模数不互素。

在这里插入图片描述
.
.
(这里积累第二个经验)
然后查了资料后发现关键在p和p1q和q1都是两两相邻的素数这里,也就是说p,q,p1,q1两两互素。单纯的factordb.comyafu分解n肯定是分解不出来的,毕竟是2048bit嘛。所以我们需要一些算法,比如前面模不互素欧几里得算法这样,这里我们要用的是费马分解算法。

费马分解算法的特征就是n4个数的乘积,分解n之后我们会得到p、p1、q、q1四组隔开的排列组合,但是我们的脚本可以把组合限定成p * q1, p1 * q,和p * q ,p1 * q这样。然后通过gcd(pq1,pq) = pgcd(p1q,p1q) = q 求出两组各一个数,然后就可以求出φ(n)=φ(p)⋅φ(p1)⋅φ(q)⋅φ(q1)=(p−1)⋅(q−1)⋅(p1−1)⋅(q1−1)了。

然后后面的参考以前积累的RSA解密流程做即可:
在这里插入图片描述
.
.
费马因子分解代码:

(取自https://blog.csdn.net/weixin_56678592/article/details/120555169?utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7Edefault-1.no_search_link&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7Edefault-1.no_search_link)
import gmpy2
from gmpy2 import *
from Crypto.Util.number import *
import sympy
e = 0x10001
n1 = 6348779979606280884589422188738902470575876294643492831465947360363568026280963989291591157710389629216109615274754718329987990551836115660879103234129921943824061416396264358110216047994331119920503431491509529604742468032906950984256964560405062345280120526771439940278606226153077959057882262745273394986607004406770035459301695806378598890589432538916219821477777021460189140081521779103226953544426441823244765828342973086422949017937701261348963541035128661464068769033772390320426795044617751909787914185985911277628404632533530390761257251552073493697518547350246993679844132297414094727147161169548160586911
c1 = 6201882078995455673376327652982610102807874783073703018551044780440620679217833227711395689114659144506630609087600915116940111002026241056808189658969089532597757995423694966667948250438579639890580690392400661711864264184444018345499567505424672090632235109624193289954785503512742400960515331371813467034511130432319427185134018830006918682733848618201088649690422818940385123599468595766345668931882249779415788129316594083269412221804774856038796248038700275509397599351533280014908894068141056694660319816046357462684688942519849441237878018480036145051967731081582598773076490918572392784684372694103015244826
def fermat_factorization(n):
    factor_list = []
    get_context().precision = 2048	#这里应该是n1的数量级吧,len(bin(n1))就等于2048bit。
    sqrt_n = int(sqrt(n))
    c = sqrt_n
    while True:
        c += 1
        d_square = c**2 - n
        if is_square(d_square):
            d_square = mpz(d_square)
            get_context().precision = 2048
            d = int(sqrt(d_square))
            factor_list.append([c+d,c-d])
        if len(factor_list)==2:
            break
    return factor_list

factor_list = fermat_factorization(n1)
[X1,Y1] = factor_list[0]	#费马函数分解最大的特征就是输出两组互相交叉的p * q1, p1 * q,和p * q ,p1 * q,我们必须用gcd(X1,X2)和gcd(Y1,Y2)求出对应的p、q
[X2,Y2] = factor_list[1]
assert X1*Y1 == n1
assert X2*Y2 == n1
p1 = gcd(X1,X2)
q1 = X1 // p1		#这是python向下取整除运算符,我真的第一次发现python有这个运算符。
p2 = gcd(Y1,Y2)
q2 = Y1 // p2

phi1 = (p1-1)*(q1-1)*(p2-1)*(q2-1)	#求φ(n)
d1 = invert(e,phi1)		#常规RSA解密流程求d
print(long_to_bytes(gmpy2.powmod(c1,d1,n1)),end='')	##常规RSA解密流程求明文
#flag{Euler_funct1ons

.
结果:
在这里插入图片描述
.
.
.
(这里积累第三个经验)
接下来分析后半段,后半段给了x+yx*y的值,按照初中数学的逻辑直接列个方程就可以解出xy的值了,但是我看别人博客各种算法来解这个简单的逻辑,什么欧拉函数,因式方程看得头都晕。

然后翻着翻着突然发现一个秀儿,他p2q2求法是这样的,因为n2=p2*p2*q2*q2*q2,所以 q2 = n2 // (p2_mul_q2*p2_mul_q2)、p2 = p2_mul_q2 // q2,真的我都鼓掌了,太棒了,简单题就简单做啊,简单的逻辑就应该这样求才对啊。

所以直接套用脚本即可,这里要注意的是φ(n)这里,因为因子只有p2q2,所以φ(n)=p2*(p2 - 1)*q2*q2*(q2 - 1),只用对单个因子减1即可。

import libnum
from Crypto.Util.number import long_to_bytes

n2=40588227045595304080360385041082238507044292731344465815296032905633525556943787610712651675460810768762763493579129831271018141591546207557410817432455139315527674932933085299277599173971912445226532235814580879585317211349524406424200622675880992390782025158621241499693400288031658194434641718026910652327933253877313106112861283314274635124734817398465059373562194694957841264834312640926278890386089611103714990646541470577351599526904458342660444968591197606820361364761648205241041444681145820799054413179462285509661124362074093583494932706249461954240408827087015525507173082129412234486228092002841868365895837463699200959915782767657258729794037776401995309244941171415842403617486719492483671490834562579225506831496881542530519595438932482796867853234159664409420977526102480385193101883785161080269573707156626838551506024455480650224305894501968583442346807126920740779780593650871645915149689424292912611578291912721896864772950410266629045542480009266574096080138709683466489568290569363478444349563498507530805502511051165160827192795520182720802422213364247355775222858214648603034743679187470844212529134374975737510982287957316878179964602394749601431823167982157434890459245394370728942790117156485268116758052636794417268680901420193002289035538753620555488506926366624641291881353268617130968991258983002165300186971963661666476600998389048880565199317280428349802824448329898502788492233381873026217202981921654673840142095839603360666049476100561268336225902504932800605464136192275593886736746497955270280541423593

p2_add_q2=274773146761138462708137582309097386437793891793691383033856524303010811294101933454824485010521468914846151819876043508541879637544444256520741418495479393777132830985856522008561088410862815913292288683761657919121930016956916865849261153721097671315883469348972925757078089715102032241818526925988645578778

p2_mul_q2=18514724270030962172566965941723224386374076294232652258701085781018776172843355920566035157331579524980108190739141959926523082142273672741849552475156278397131571360099018592018959785627785130126477982765210498547680367230723634424036009539347854344573537848628061468892166199866227984167843139793429682559241317072979374002912607549039431398267184818771503468116379618249319324788996321340764624593443106354104274472601170229835219638093242557547840060892527576940077162990069687019966946826210112318408269749294366586682732614372434218768720577917368726530200897558912687470088583774711767599580037663378929000217

e = 0x10001

c2 = 25591090168544821761746024178724660839590948190451329227481168576490717242294520739865602061082558759751196452117720647426598261568572440942370039702932821941366792140173428488344932203576334292648255551171274828821657097667106792872200082579319963310503721435500623146012954474613150848083425126987554594651797477741828655238243550266972216752593788734836373144363217639612492397228808215205862281278774096317615918854403992620720969173788151215489908812749179861803144937169587452008097008940710091361183942268245271154461872102813602754439939747566507116519362821255724179093051041994730856401493996771276172343313045755916751082693149885922105491818225012844519264933137622929024918619477538521533548551789739698933067212305578480416163609137189891797209277557411169643568540392303036719952140554435338851671440952865151077383220305295001632816442144022437763089133141886924265774247290306669825085862351732336395617276100374237159580759999593028756939354840677333467281632435767033150052439262501059299035212928041546259933118564251119588970009016873855478556588250138969938599988198494567241172399453741709840486953189764289118312870580993115636710724139809708256360212728127786394411676427828431569046279687481368215137561500777480380501551616577832499521295655237360184159889151837766353116185320317774645294201044772828099074917077896631909654671612557207653830344897644115936322128351494551004652981550758791285434809816872381900401440743578104582305215488888563166054568802145921399726673752722820646807494657299104190123945675647

q2 = n2 // (p2_mul_q2*p2_mul_q2)
p2 = p2_mul_q2 // q2
d2 = libnum.invmod(e, p2*(p2 - 1)*q2*q2*(q2 - 1))		#invmod(a, n) - 求a对于n的模逆,这里逆向加密过程中计算ψ(n)=(p-1)(q-1),对ψ(n)保密,也就是对应根据e*d=1modψ(n),求出d
m = pow(c2, d2, n2)   # 这里的m是十进制形式,pow(x, y[, z])--函数是计算 x 的 y 次方,如果 z 在存在,则再对结果进行取模,其结果等效于 pow(x,y) %z,对应前面解密算法中M=D(C)=(C^d)mod n
string = long_to_bytes(m)  # 获取m明文
print(string)

.
结果:
在这里插入图片描述
.
.
.
总结:

1:
(这里积累第一个经验)
先看第一段,gmpy2.next_prime(p)函数的意思是取邻近p的下一个素数,那么很明显p和p1q和q1都是两两相邻的素数,相差很小,n12048bit级别的,没法硬钢。
.
后半段的n2和前半段的加密逻辑差别很大,所以不是两个n的模不互素。也不是像上一道题RSA1一样的密文与模数不互素。
.

2:
(这里积累第二个经验)
然后查了资料后发现关键在p和p1q和q1都是两两相邻的素数这里,也就是说p,q,p1,q1两两互素。单纯的factordb.comyafu分解n肯定是分解不出来的,毕竟是2048bit嘛。所以我们需要一些算法,比如前面模不互素欧几里得算法这样,这里我们要用的是费马分解算法。

费马分解算法的特征就是n4个数的乘积,分解n之后我们会得到p、p1、q、q1四组隔开的排列组合,但是我们的脚本可以把组合限定成`p

  • q1, p1 * q,和p * q ,p1 * q这样。然后通过gcd(pq1,pq) = pgcd(p1q,p1q) = q求出两组各一个数,然后就可以求出φ(n)=φ§⋅φ(p1)⋅φ(q)⋅φ(q1)=(p−1)⋅(q−1)⋅(p1−1)⋅(q1−1)`了。

然后后面的参考以前积累的RSA解密流程做即可:
在这里插入图片描述

3:
(这里积累第三个经验)
接下来分析后半段,后半段给了x+yx*y的值,按照初中数学的逻辑直接列个方程就可以解出xy的值了,但是我看别人博客各种算法来解这个简单的逻辑,什么欧拉函数,因式方程看得头都晕。
.
然后翻着翻着突然发现一个秀儿,他p2q2求法是这样的,因为n2=p2*p2*q2*q2*q2,所以 q2 = n2 // (p2_mul_q2*p2_mul_q2)、p2 = p2_mul_q2 // q2,真的我都鼓掌了,太棒了,简单题就简单做啊,简单的逻辑就应该这样求才对啊。
.
所以直接套用脚本即可,这里要注意的是φ(n)这里,因为因子只有p2q2,所以φ(n)=p2*(p2 - 1)*q2*q2*(q2 - 1),只用对单个因子减1即可。

解毕!敬礼!

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

沐一 · 林

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值