金歌 发表于 2024-11-4 00:37:11

MoeCTF2024--Crypto--Week1&Week2

MOECTF        (CRYPTO)

Week1:

1.入门指北

标题:

from Crypto.Util.number import bytes_to_long, getPrime
from secret import flag
p = getPrime(128)
q = getPrime(128)
n = p*q
e = 65537
m = bytes_to_long(flag)
c = pow(m, e, n)
print(f"n = {n}")
print(f"p = {p}")
print(f"q = {q}")
print(f"c = {c}")
'''
n = 40600296529065757616876034307502386207424439675894291036278463517602256790833
p = 197380555956482914197022424175976066223
q = 205695522197318297682903544013139543071
c = 36450632910287169149899281952743051320560762944710752155402435752196566406306
'''标题分析:

这是一道简单的RSA,数据也已经给出,利用python中的Crypto库中的函数写解密脚本即可。
解密脚本:

from Crypto.Util.number import inverse, long_to_bytes

# 给定数据
n = 40600296529065757616876034307502386207424439675894291036278463517602256790833
p = 197380555956482914197022424175976066223
q = 205695522197318297682903544013139543071
e = 65537
c = 36450632910287169149899281952743051320560762944710752155402435752196566406306

# 计算 φ(n)
phi_n = (p - 1) * (q - 1)

# 计算私钥 d
d = inverse(e, phi_n)

# 解密密文 c
m = pow(c, d, n)

# 将解密得到的数字转换为字节
flag = long_to_bytes(m)

# 打印结果
print("解密得到的 flag:", flag.decode())
# moectf{the_way_to_crypto}2.Signin

标题:

from Crypto.Util.number import*
from secret import flag


m = bytes_to_long(flag)
p = getPrime(1024)
q = getPrime(1024)
n = p*q
e = 65537
c = pow(m,e,n)
pq = (p-1)*(q-2)
qp = (q-1)*(p-2)
p_q = p + q


print(f"{c = }")
print(f"{pq = }")
print(f"{qp = }")
print(f"{n = }")
print(f"{p_q = }")
'''
c = 5654386228732582062836480859915557858019553457231956237167652323191768422394980061906028416785155458721240012614551996577092521454960121688179565370052222983096211611352630963027300416387011219744891121506834201808533675072141450111382372702075488292867077512403293072053681315714857246273046785264966933854754543533442866929316042885151966997466549713023923528666038905359773392516627983694351534177829247262148749867874156066768643169675380054673701641774814655290118723774060082161615682005335103074445205806731112430609256580951996554318845128022415956933291151825345962528562570998777860222407032989708801549746
pq = 18047017539289114275195019384090026530425758236625347121394903879980914618669633902668100353788910470141976640337675700570573127020693081175961988571621759711122062452192526924744760561788625702044632350319245961013430665853071569777307047934247268954386678746085438134169871118814865536503043639618655569687154230787854196153067547938936776488741864214499155892870610823979739278296501074632962069426593691194105670021035337609896886690049677222778251559566664735419100459953672218523709852732976706321086266274840999100037702428847290063111455101343033924136386513077951516363739936487970952511422443500922412450462
qp = 18047017539289114275195019384090026530425758236625347121394903879980914618669633902668100353788910470141976640337675700570573127020693081175961988571621759711122062452192526924744760561788625702044632350319245961013430665853071569777307047934247268954386678746085438134169871118814865536503043639618655569687077087914198877794354459669808240133383828356379423767736753506794441545506312066344576298453957064590180141648690226266236642320508613544047037110363523129966437840660693885863331837516125853621802358973786440314619135781324447765480391038912783714312479080029167695447650048419230865326299964671353746764860
n = 18047017539289114275195019384090026530425758236625347121394903879980914618669633902668100353788910470141976640337675700570573127020693081175961988571621759711122062452192526924744760561788625702044632350319245961013430665853071569777307047934247268954386678746085438134169871118814865536503043639618655569687534959910892789661065614807265825078942931717855566686073463382398417205648946713373617006449901977718981043020664616841303517708207413215548110294271101267236070252015782044263961319221848136717220979435486850254298686692230935985442120369913666939804135884857831857184001072678312992442792825575636200505903
p_q = 279533706577501791569740668595544511920056954944184570513187478007551195831693428589898548339751066551225424790534556602157835468618845221423643972870671556362200734472399328046960316064864571163851111207448753697980178391430044714097464866523838747053135392202848167518870720149808055682621080992998747265496
'''标题分析:

Signin相较于指北就是通过简单的数学算式隐藏了p,q的数据。

\
通过简单的加减消元即可还原p,q的数据。
解密脚本:

from Crypto.Util.number import*

#Given values
c = 5654386228732582062836480859915557858019553457231956237167652323191768422394980061906028416785155458721240012614551996577092521454960121688179565370052222983096211611352630963027300416387011219744891121506834201808533675072141450111382372702075488292867077512403293072053681315714857246273046785264966933854754543533442866929316042885151966997466549713023923528666038905359773392516627983694351534177829247262148749867874156066768643169675380054673701641774814655290118723774060082161615682005335103074445205806731112430609256580951996554318845128022415956933291151825345962528562570998777860222407032989708801549746
pq = 18047017539289114275195019384090026530425758236625347121394903879980914618669633902668100353788910470141976640337675700570573127020693081175961988571621759711122062452192526924744760561788625702044632350319245961013430665853071569777307047934247268954386678746085438134169871118814865536503043639618655569687154230787854196153067547938936776488741864214499155892870610823979739278296501074632962069426593691194105670021035337609896886690049677222778251559566664735419100459953672218523709852732976706321086266274840999100037702428847290063111455101343033924136386513077951516363739936487970952511422443500922412450462
qp = 18047017539289114275195019384090026530425758236625347121394903879980914618669633902668100353788910470141976640337675700570573127020693081175961988571621759711122062452192526924744760561788625702044632350319245961013430665853071569777307047934247268954386678746085438134169871118814865536503043639618655569687077087914198877794354459669808240133383828356379423767736753506794441545506312066344576298453957064590180141648690226266236642320508613544047037110363523129966437840660693885863331837516125853621802358973786440314619135781324447765480391038912783714312479080029167695447650048419230865326299964671353746764860
n = 18047017539289114275195019384090026530425758236625347121394903879980914618669633902668100353788910470141976640337675700570573127020693081175961988571621759711122062452192526924744760561788625702044632350319245961013430665853071569777307047934247268954386678746085438134169871118814865536503043639618655569687534959910892789661065614807265825078942931717855566686073463382398417205648946713373617006449901977718981043020664616841303517708207413215548110294271101267236070252015782044263961319221848136717220979435486850254298686692230935985442120369913666939804135884857831857184001072678312992442792825575636200505903
p_q = 279533706577501791569740668595544511920056954944184570513187478007551195831693428589898548339751066551225424790534556602157835468618845221423643972870671556362200734472399328046960316064864571163851111207448753697980178391430044714097464866523838747053135392202848167518870720149808055682621080992998747265496
e = 65537

#通过加减消元还原p,q
p = (p_q-(pq-qp))// 2
q = (p_q+(pq-qp))//2

#获取密钥进行RSA解密
d = inverse(e,(p-1)*(q-1))
m = pow(c,d,n)
flag = long_to_bytes(m)
print(flag)
# moectf{Just_4_signin_ch4ll3ng3_for_y0u}3.ez_hash

标题:

from hashlib import sha256
from secret import flag, secrets

assert flag == b'moectf{' + secrets + b'}'
assert secrets[:4] == b'2100' and len(secrets) == 10
hash_value = sha256(secrets).hexdigest()
print(f"{hash_value = }")
# hash_value = '3a5137149f705e4da1bf6742e62c018e3f7a1784ceebcb0030656a2b42f50b6a'标题分析:

这是一道入门哈希加密(SHA256)的标题,关于哈希加密,保举CSDN上的一篇文章(https://blog.csdn.net/javasimawanyi/article/details/131643604)。flag根据SHA256的特点进行简单的爆破即可,如果没有爆破出来,就简单地调整一下爆破范围。如果标题中数据量过大,就需要根据标题中的要求去优化算法。
解密脚本:

from hashlib import sha256

# 给定的 hash_value
hash_value = '3a5137149f705e4da1bf6742e62c018e3f7a1784ceebcb0030656a2b42f50b6a'

# 尝试所有可能的 secrets
for i in range(10000, 1000000000):
    secrets = b'2100' + str(i).zfill(6).encode()
    if sha256(secrets).hexdigest() == hash_value:
      flag = b'moectf{' + secrets + b'}'
      print(f"Found flag: {flag.decode()}")
      break
# moectf{2100360168}4.Big and small

标题:

from secret import flag
from Crypto.Util.number import*
m = long_to_bytes(flag)
p = getPrime(1024)
q = getPrime(1024)
n = p*q
e = 3
c = pow(m,e,n)
'''
c = 150409620528288093947185249913242033500530715593845912018225648212915478065982806112747164334970339684262757
e = 3
n = 20279309983698966932589436610174513524888616098014944133902125993694471293062261713076591251054086174169670848598415548609375570643330808663804049384020949389856831520202461767497906977295453545771698220639545101966866003886108320987081153619862170206953817850993602202650467676163476075276351519648193219850062278314841385459627485588891326899019745457679891867632849975694274064320723175687748633644074614068978098629566677125696150343248924059801632081514235975357906763251498042129457546586971828204136347260818828746304688911632041538714834683709493303900837361850396599138626509382069186433843547745480160634787
'''标题分析:

由标题分析可知这是一道RSA标题,而且e是3,除2之外最小的素数,它的因数里面只有1和3,因此只需要对c开三次方获取m即可。
解密脚本:

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

c = 150409620528288093947185249913242033500530715593845912018225648212915478065982806112747164334970339684262757
print('moectf{' + long_to_bytes(iroot(c,3)).decode() + '}')
# flag{xt>is>s>b}5.baby_equation

标题:

from Crypto.Util.number import *
from secret import flag


l = len(flag)
m1, m2 = flag[:l//2], flag
a = bytes_to_long(m1)
b = bytes_to_long(m2)
k = 0x2227e398fc6ffcf5159863a345df85ba50d6845f8c06747769fee78f598e7cb1bcf875fb9e5a69ddd39da950f21cb49581c3487c29b7c61da0f584c32ea21ce1edda7f09a6e4c3ae3b4c8c12002bb2dfd0951037d3773a216e209900e51c7d78a0066aa9a387b068acbd4fb3168e915f306ba40
assert ((a**2 + 1)*(b**2 + 1) - 2*(a - b)*(a*b - 1)) == 4*(k + a*b)标题分析:

这是一道大素数分解的数论暗码题。思路如下:
1.先化简标题中的断言式子:

\[\begin{flalign}&(a²+1)(b²+1)-2(a-b)(ab-1)=4(k+ab);\\&[(a-b)(ab-1)]²+4ab=4k+4ab\\&a-b-ab+1=2√k\\&(a+1)(b-1)=2√k&\end{flalign}\]
2.通过yafu(https://github.com/bbuhrow/yafu)对k进行素数分解
如许你会得到成双成对的小素数,将的一半他们进行相乘就是√k,进而继承求解2√k
3.接着我们发现(a+1)和(b-1)是2√k的两个因数,再去对2√k进行yafu因数分解
如许我们会得到一个最大的素因数,同时对别的的一个因数分解,我们会得到17个互素的数,这个时候我们就可以先进行求解(a+1),(b-1)求解的根据就是
l = len(flag)
m1, m2 = flag[:l//2], flag
a = bytes_to_long(m1)
b = bytes_to_long(m2)进而求解a,b,flag.
4.我的思路是通过先循环遍历随机两个数的组合,再利用整除求出别的一个因数,利用
len(long_to_bytes(a))==len(long_to_bytes(b))和判断a的前缀是否是moectf{
随机两个数组合,没有输出后就3,4,5……这道题跑到10即可。
解密脚本:

from Crypto.Util.number import *
from itertools import combinations
from Crypto.Util.number import long_to_bytes

#判断a转化为字符串之后的前缀是不是moectf{
def starts_with_moectf(a):
    # 将整数a转换为字节串
    byte_str = long_to_bytes(a)
    # 目标前缀
    prefix = b"moectf{"
    # 检查字节串的前7个字节是否是目标前缀
    return byte_str.startswith(prefix)

#对于转化后的方程(a + 1)*(b - 1) = 2 * k** 0.5
numbers =
k = 2*2*2*2*3*3*31*61*223*4013*281317*4151351*5404604441993*339386329*26798471753993*25866088332911027256931479223*64889106213996537255229963986303510188999911*370523737

# 遍历所有两两组合(无输出后进而递增)
for a, b, c, d, e, f, g, h, i, j in combinations(numbers, 10):
    x = a * b * c * d * e * f * g * h * i * j
    y = k // x
    if(len(long_to_bytes(x-1))==len(long_to_bytes(y+1)) and starts_with_moectf(x-1)):
      print(long_to_bytes(x-1)+long_to_bytes(y+1))
# moectf{7he_Fund4m3nt4l_th30r3m_0f_4rithm3tic_i5_p0w4rful!}Week2:

1.大白兔

标题:

from Crypto.Util.number import *

flag = b'moectf{xxxxxxxxxx}'
m = bytes_to_long(flag)

e1 = 12886657667389660800780796462970504910193928992888518978200029826975978624718627799215564700096007849924866627154987365059524315097631111242449314835868137
e2 = 12110586673991788415780355139635579057920926864887110308343229256046868242179445444897790171351302575188607117081580121488253540215781625598048021161675697


def encrypt(m, e1, e2):
    p = getPrime(512)
    q = getPrime(512)
    N = p * q
    c1 = pow((3 * p + 7 * q), e1, N)
    c2 = pow((2 * p + 5 * q), e2, N)
    e = 65537
    c = pow(m, e, N)
    return c


print(encrypt(m, e1, e2))

'''
N = 107840121617107284699019090755767399009554361670188656102287857367092313896799727185137951450003247965287300048132826912467422962758914809476564079425779097585271563973653308788065070590668934509937791637166407147571226702362485442679293305752947015356987589781998813882776841558543311396327103000285832158267
c1 = 15278844009298149463236710060119404122281203585460351155794211733716186259289419248721909282013233358914974167205731639272302971369075321450669419689268407608888816060862821686659088366316321953682936422067632021137937376646898475874811704685412676289281874194427175778134400538795937306359483779509843470045
c2 = 21094604591001258468822028459854756976693597859353651781642590543104398882448014423389799438692388258400734914492082531343013931478752601777032815369293749155925484130072691903725072096643826915317436719353858305966176758359761523170683475946913692317028587403027415142211886317152812178943344234591487108474
c = 21770231043448943684137443679409353766384859347908158264676803189707943062309013723698099073818477179441395009450511276043831958306355425252049047563947202180509717848175083113955255931885159933086221453965914552773593606054520151827862155643433544585058451821992566091775233163599161774796561236063625305050
'''标题分析:

这是一个数学式子的推导。

\

\
N = p * q, 多项式睁开。

\

\

\

\

\
由此可知N与上式具有公因子p。利用最大公约数可以求出p,进而进行RSA解密。
解密脚本:

from Crypto.Util.number import *

N = 107840121617107284699019090755767399009554361670188656102287857367092313896799727185137951450003247965287300048132826912467422962758914809476564079425779097585271563973653308788065070590668934509937791637166407147571226702362485442679293305752947015356987589781998813882776841558543311396327103000285832158267
c1 = 15278844009298149463236710060119404122281203585460351155794211733716186259289419248721909282013233358914974167205731639272302971369075321450669419689268407608888816060862821686659088366316321953682936422067632021137937376646898475874811704685412676289281874194427175778134400538795937306359483779509843470045
c2 = 21094604591001258468822028459854756976693597859353651781642590543104398882448014423389799438692388258400734914492082531343013931478752601777032815369293749155925484130072691903725072096643826915317436719353858305966176758359761523170683475946913692317028587403027415142211886317152812178943344234591487108474
c = 21770231043448943684137443679409353766384859347908158264676803189707943062309013723698099073818477179441395009450511276043831958306355425252049047563947202180509717848175083113955255931885159933086221453965914552773593606054520151827862155643433544585058451821992566091775233163599161774796561236063625305050

e1 = 12886657667389660800780796462970504910193928992888518978200029826975978624718627799215564700096007849924866627154987365059524315097631111242449314835868137
e2 = 12110586673991788415780355139635579057920926864887110308343229256046868242179445444897790171351302575188607117081580121488253540215781625598048021161675697

p=GCD(N, pow(c1, e2,N)*pow(5, e1*e2,N)-pow(c2, e1,N)*pow(7, e1*e2,N))
q=N//p
print(long_to_bytes(pow(c, inverse(65537, (p-1)*(q-1)),N)))
# moectf{Sh4!!0w_deeb4t0_P01arnova}2.more_secure_RSA

标题:

from Crypto.Util.number import *

flag = b'moectf{xxxxxxxxxxxxxxxxx}'


m = bytes_to_long(flag)
p = getPrime(1024)
q = getPrime(1024)
n = p * q
e = 0x10001
c = pow(m, e, n)
print(f'c = {c}')
print(f'n = {n}')

'''
Oh,it isn't secure enough!
'''
r = getPrime(1024)
n = n * r
c = pow(m, e, n)
print(f'C = {c}')
print(f'N = {n}')

'''
c = 12992001402636687796268040906463852467529970619872166160007439409443075922491126428847990768804065656732371491774347799153093983118784555645908829567829548859716413703103209412482479508343241998746249393768508777622820076455330613128741381912099938105655018512573026861940845244466234378454245880629342180767100764598827416092526417994583641312226881576127632370028945947135323079587274787414572359073029332698851987672702157745794918609888672070493920551556186777642058518490585668611348975669471428437362746100320309846155934102756433753034162932191229328675448044938003423750406476228868496511462133634606503693079
n = 16760451201391024696418913179234861888113832949815649025201341186309388740780898642590379902259593220641452627925947802309781199156988046583854929589247527084026680464342103254634748964055033978328252761138909542146887482496813497896976832003216423447393810177016885992747522928136591835072195940398326424124029565251687167288485208146954678847038593953469848332815562187712001459140478020493313651426887636649268670397448218362549694265319848881027371779537447178555467759075683890711378208297971106626715743420508210599451447691532788685271412002723151323393995544873109062325826624960729007816102008198301645376867
C = 1227033973455439811038965425016278272592822512256148222404772464092642222302372689559402052996223110030680007093325025949747279355588869610656002059632685923872583886766517117583919384724629204452792737574445503481745695471566288752636639781636328540996436873887919128841538555313423836184797745537334236330889208413647074397092468650216303253820651869085588312638684722811238160039030594617522353067149762052873350299600889103069287265886917090425220904041840138118263873905802974197870859876987498993203027783705816687972808545961406313020500064095748870911561417904189058228917692021384088878397661756664374001122513267695267328164638124063984860445614300596622724681078873949436838102653185753255893379061574117715898417467680511056057317389854185497208849779847977169612242457941087161796645858881075586042016211743804958051233958262543770583176092221108309442538853893897999632683991081144231262128099816782478630830512
N = 1582486998399823540384313363363200260039711250093373548450892400684356890467422451159815746483347199068277830442685312502502514973605405506156013209395631708510855837597653498237290013890476973370263029834010665311042146273467094659451409034794827522542915103958741659248650774670557720668659089460310790788084368196624348469099001192897822358856214600885522908210687134137858300443670196386746010492684253036113022895437366747816728740885167967611021884779088402351311559013670949736441410139393856449468509407623330301946032314939458008738468741010360957434872591481558393042769373898724673597908686260890901656655294366875485821714239821243979564573095617073080807533166477233759321906588148907331569823186970816432053078415316559827307902239918504432915818595223579467402557885923581022810437311450172587275470923899187494633883841322542969792396699601487817033616266657366148353065324836976610554682254923012474470450197
'''标题分析:

c=m^e mod n,p是n的一个因子,如果m<p,根据取模的性质,那么c=m^e mod p也就成立,因为r是1024位,m的长度应该<r,以是我就直接转移到r上了。m=pow(C,inverse(e,r-1),r)。r通过N//n可以求。2个因数的情况下必须要求一个的话,就没必要转到因子上了。
解密脚本:

from Crypto.Util.number import *

c = 12992001402636687796268040906463852467529970619872166160007439409443075922491126428847990768804065656732371491774347799153093983118784555645908829567829548859716413703103209412482479508343241998746249393768508777622820076455330613128741381912099938105655018512573026861940845244466234378454245880629342180767100764598827416092526417994583641312226881576127632370028945947135323079587274787414572359073029332698851987672702157745794918609888672070493920551556186777642058518490585668611348975669471428437362746100320309846155934102756433753034162932191229328675448044938003423750406476228868496511462133634606503693079
n = 16760451201391024696418913179234861888113832949815649025201341186309388740780898642590379902259593220641452627925947802309781199156988046583854929589247527084026680464342103254634748964055033978328252761138909542146887482496813497896976832003216423447393810177016885992747522928136591835072195940398326424124029565251687167288485208146954678847038593953469848332815562187712001459140478020493313651426887636649268670397448218362549694265319848881027371779537447178555467759075683890711378208297971106626715743420508210599451447691532788685271412002723151323393995544873109062325826624960729007816102008198301645376867
C = 1227033973455439811038965425016278272592822512256148222404772464092642222302372689559402052996223110030680007093325025949747279355588869610656002059632685923872583886766517117583919384724629204452792737574445503481745695471566288752636639781636328540996436873887919128841538555313423836184797745537334236330889208413647074397092468650216303253820651869085588312638684722811238160039030594617522353067149762052873350299600889103069287265886917090425220904041840138118263873905802974197870859876987498993203027783705816687972808545961406313020500064095748870911561417904189058228917692021384088878397661756664374001122513267695267328164638124063984860445614300596622724681078873949436838102653185753255893379061574117715898417467680511056057317389854185497208849779847977169612242457941087161796645858881075586042016211743804958051233958262543770583176092221108309442538853893897999632683991081144231262128099816782478630830512
N = 1582486998399823540384313363363200260039711250093373548450892400684356890467422451159815746483347199068277830442685312502502514973605405506156013209395631708510855837597653498237290013890476973370263029834010665311042146273467094659451409034794827522542915103958741659248650774670557720668659089460310790788084368196624348469099001192897822358856214600885522908210687134137858300443670196386746010492684253036113022895437366747816728740885167967611021884779088402351311559013670949736441410139393856449468509407623330301946032314939458008738468741010360957434872591481558393042769373898724673597908686260890901656655294366875485821714239821243979564573095617073080807533166477233759321906588148907331569823186970816432053078415316559827307902239918504432915818595223579467402557885923581022810437311450172587275470923899187494633883841322542969792396699601487817033616266657366148353065324836976610554682254923012474470450197
e = 65537

r = N // n
flag = long_to_bytes(pow(C,inverse(e,r-1),r))
print(flag)
# moectf{th3_a1g3br4_is_s0_m@gic!}3.ezlegendre

标题:

from Crypto.Util.number import *

p = getPrime(128)
a = randprime(2, p)

FLAG = b'moectf{xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}'


def encrypt_flag(flag):
    ciphertext = []
    plaintext = ''.join(.zfill(8) for i in flag])
    for bit in plaintext:
      e = randprime(2, p)
      n = pow(int(bit) + a, e , p)
      ciphertext.append(n)
    return ciphertext

print(encrypt_flag(FLAG))

'''
p = 303597842163255391032954159827039706827
a = 34032839867482535877794289018590990371
[…………](数据在解密脚本中)
'''标题分析:

根据标题“ezlegendre”,去学习勒让德符号(https://blog.csdn.net/weixin_46447549/article/details/114372252)
根据勒让德符号(雅可比符号)的用途,去判断(bit)是'0' or '1'。下面提供两种表明。
1.因为e是素数,那么把(a+bit)拆出来一个,如果bit = 1,那么(a+bit)一定是一个偶数,可以拆成

\
e-1一定是偶数,那么就是有二次剩余了,雅可比符号!=-1
2.可以看一下(a+1)和a是不是n的二次剩余,刚好一个是,一个不是。
解密脚本:

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

p = 303597842163255391032954159827039706827
a = 34032839867482535877794289018590990371
ciphertxt =

flag = ''

for n in ciphertxt:
    if jacobi(n,p)==-1:
      flag += '0'
    else:
      flag += '1'
flag = int(flag,2)
print(long_to_bytes(flag))
# moectf{minus_one_1s_n0t_qu4dr4tic_r4sidu4_when_p_mod_f0ur_equ41_to_thr33}4.new_system

标题:

from random import randint
from Crypto.Util.number import getPrime,bytes_to_long


flag = b'moectf{???????????????}'
gift = bytes_to_long(flag)


def parametergenerate():
    q = getPrime(256)
    gift1 = randint(1, q)
    gift2 = (gift - gift1) % q
    x =randint(1, q)
    assert gift == (gift1 + gift2) % q
    return q , x , gift1, gift2


def encrypt(m , q , x):
    a = randint(1, q)
    c = (a*x + m) % q
    return


q , x , gift1 , gift2 = parametergenerate()
print(encrypt(gift1 , q , x))
print(encrypt(gift2 , q , x))
print(encrypt(gift , q , x))
print(f'q = {q}')

'''



q = 105482865285555225519947662900872028851795846950902311343782163147659668129411标题分析:

分析parametergenerate函数后,就是一个产生参数的一个函数,其次encrypt进行加密。
分析加密过程就可以写出三个等式:

\

\

\
已知:

\
进行1+2-3化简后就可以得到:

\
由此可得到x,经3式还原得到gift:

\
解密脚本:

from Crypto.Util.number import *

gift1_a_c =
gift2_a_c =
gift_a_c =
q = 105482865285555225519947662900872028851795846950902311343782163147659668129411

x = inverse(gift1_a_c+gift2_a_c-gift_a_c,q)*(gift1_a_c+gift2_a_c-gift_a_c) % q
gift = (gift_a_c-gift_a_c*x) % q
print(long_to_bytes(gift))
# moectf{gift_1s_present}5.RSA_revenge

标题:

from Crypto.Util.number import getPrime, isPrime, bytes_to_long
from secret import flag


def emirp(x):
    y = 0
    while x !=0:
      y = y*2 + x%2
      x = x//2
    return y


while True:
    p = getPrime(512)
    q = emirp(p)
    if isPrime(q):
      break

n = p*q
e = 65537
m = bytes_to_long(flag)
c = pow(m,e,n)
print(f"{n = }")
print(f"{c = }")

"""
n = 141326884939079067429645084585831428717383389026212274986490638181168709713585245213459139281395768330637635670530286514361666351728405851224861268366256203851725349214834643460959210675733248662738509224865058748116797242931605149244469367508052164539306170883496415576116236739853057847265650027628600443901
c = 47886145637416465474967586561554275347396273686722042112754589742652411190694422563845157055397690806283389102421131949492150512820301748529122456307491407924640312270962219946993529007414812671985960186335307490596107298906467618684990500775058344576523751336171093010950665199612378376864378029545530793597
"""标题分析:

根据标题的分析,emirp是将给入的参数转化为二进制之后进行反转。即p,q都是素数,并且两者的二进制数是相互反转的。是一道经典的byte by byte的题型。因此我们只需要利用递归函数并且多加限定条件来简化大素数分解问题即可。
解密脚本:

from Crypto.Util.number import *

n = 141326884939079067429645084585831428717383389026212274986490638181168709713585245213459139281395768330637635670530286514361666351728405851224861268366256203851725349214834643460959210675733248662738509224865058748116797242931605149244469367508052164539306170883496415576116236739853057847265650027628600443901
c = 47886145637416465474967586561554275347396273686722042112754589742652411190694422563845157055397690806283389102421131949492150512820301748529122456307491407924640312270962219946993529007414812671985960186335307490596107298906467618684990500775058344576523751336171093010950665199612378376864378029545530793597


def find(p,q,bits,c):
    if bits==256:
      if p*q==n:
            print('Find!')
            print(p)
            q=n//p
            print(long_to_bytes(pow(c, inverse(65537, (p-1)*(q-1)),n)))
    for pp in range(2):
      for qq in range(2):
            tmp_p=p+pp*2**(511-bits)+qq*2**bits
            tmp_q=q+qq*2**(511-bits)+pp*2**bits
            if tmp_p*tmp_q<=n and (tmp_p+2**(511-bits))*(tmp_q+2**(511-bits))>=n and tmp_p*tmp_q%(2**(bits+1))==n%(2**(bits+1)):
                find(tmp_p, tmp_q, bits+1, c)

find(0, 0, 0, c)
# moectf{WA!y0u@er***g00((d))}Week3

1.One more bit

标题:

from Crypto.Util.number import *
from secret import flag
import random


p = 2050446265000552948792079248541986570794560388346670845037360320379574792744856498763181701382659864976718683844252858211123523214530581897113968018397826268834076569364339813627884756499465068203125112750486486807221544715872861263738186430034771887175398652172387692870928081940083735448965507812844169983643977
assert len(flag) == 42


def encode(msg):
    return bin(bytes_to_long(msg)).zfill(8*len(msg))


def genkey(len):
    sums = 0
    keys = []
    for i in range(len):
      k = random.randint(1,7777)
      x = sums + k
      keys.append(x)
      sums += x
    return keys


key = genkey(42*8)


def enc(m, keys):
    msg = encode(m)
    print(len(keys))
    print(len(msg))
    assert len(msg) == len(keys)
    s = sum((k if (int(p,2) == 1) else 1) for p, k in zip(msg, keys))
    print(msg)
    for p0,k in zip(msg,keys):
      print(int(p0,2))
    return pow(7,s,p)


cipher = enc(flag,key)

with open("output.txt", "w") as fs:
    fs.write(str(key)+'\n')
    fs.write(str(cipher))输出:


12105525860721544798674267767581074631692445111869916281415044001990249363392968451325076555899334797680445984189321766901083791402984807904055515730610056559092914622476755848688400351418935567487702663378955718891284225776132234527973295553811972155335513391468071878910708473484542142315050988348138710225091862.EZMatrix

标题:

from Crypto.Util.number import *from secret import FLAG,secrets,SECERT_Tassert len(secrets) == 16assert FLAG == b'moectf{' + secrets + b'}'assert len(SECERT_T)
页: [1]
查看完整版本: MoeCTF2024--Crypto--Week1&Week2