CTF-Crypto练习

技能兴鲁初赛

from gmpy2 import *
from Crypto.Util.number import *
 
flag  = 'flag{I\'m not gonna tell you the FLAG}' # 这个肯定不是FLAG了,不要交这个咯

p = getPrime(2048)
q = getPrime(2048)
m1 = bytes_to_long(bytes(flag.encode()))

e1 = 3247473589
e2 = 3698409173
n = p*q

flag1 = pow(m1,e1,n)
flag2 = pow(m1,e2,n)
print('flag1= '+str(flag1))
print('flag2= '+str(flag2))
print('n= '+str(n))


# flag1= 295658788074157816670393593671184451782123605135184996662528766686642109492132533952160456440919197939935742027629210419312032730004032666912404179229952394343569590488768472800784830058534578639706805456277578757250365834591813481786084959844340418320620440636997732915872346619679993987903742079972676425404864295283955565746004124045155664762158516005326368384488346997494926539295740248007606864906884407198601326915643000764477435205579583836917598642053869541648731754384026407310786288997756775232852732033054591953078116290088267188296560877481534143707414153749140670404213262630122369941889862912426176115220410931992046973925991075473656781794097329513119548617920256625579072719981729556158392454956362838720993254919638177786730004086883044525967823454986241038123671907279715773848673713008902432841449556980494600938989397567019338970200872333713986608537678650318511128703055185979834233315117153115613952940778789222515375743186066883492596068186378372611075958909412662251913621375996518671118244409393829141365207153662416265238312206577474940661548038715230313608405518108581922154335405303862701783678336161505643508831482409054761542959278392940037561736468155509922530420964726953308604138731805543997557197893
# flag2= 219454357017359138238563345020257296433275019950745269658921329153689267055871241202626317639487122341365759606018366576305678949982408366815977617307888894995289951707241009621444691307275542686770303994110416384086739599181934011812163156338859395115724413628620575935425221522079154607411877822646179457455118804970038865452163833416447505142114976758532806787419762250921421272492466133659234602794242531776209324085944417173098820895755851386042954303555790085402616519592065446023510096773546730662074307900123349548340507067971393642039476326402523930789953483843698593104578179169624886357604650615249286150367204109726460230037005175927865466199600272190112483494387929732049738312695796015009178606906549093365261114132002222704510637261038978031857378729856467918978246977163353146981239215886053379980533235786905270211605457443266127512667882149285155542735532327780898540341696557860555884277608448996773250847560675650046440569736010800155992053362696097992699863059686881689842065077997427372972290872427656847223849769329713841670853267584161386494525686204330028142217737052411422895042170169703550774908415280261731967511925122636118468176645781785352430657090024109246103061415446942211482659025722233229083093876
# n= 5497857005549635433932229749822e11136067042846536450239199968863551137077564447156832697813202963334596948298760762991663065504535035143397250208506445202607659676332816610122258862787906629525548439909792727593939957178783466989816894454522630301104349317697612174888605090061231211194974337772507249418567229560145454791075929946332668360553910328900103264562348881791004831033587660163923517440406942993348972589262051083908075790422096042338651001937740085414301019827335549437397656318095919875053213333008551761167437683250592542156348138055482054331330609375930693247365749085041596578748797801601289693449629548744535914348450016287545136436964138806081283470239420969311905998245715160353982174880912315601876305613349276824998688275587308133069178764001924866079232824850209407236694426779262951463035278887804883917516580169051530590466082511045503107508117656821592538792566264160105940730326929474477787053681516844548383814388361089499629312831727731267796167205124844987064389097138747938870221504684958713047985374714612321540288239995935347905120710583169131356970267386562665138437631517802641426575996558648777831102462652517305151412695166331935115971277205305816897886952646432233312318756155702046584205507027737

由于给出的p q素数都是一样的,n便是相同的! 共模攻击!

当题目给予我们多组e(公钥)和c(密文)的时候,他们共用同一个n,并且e1 e2互质的时候,存在gcd(e1,e2)=1,根据扩展的欧几里得算法,一定存在整数x,y使得e1*x+e2*y=1,我们可以通过调用gmpy2.gcdext()来运用欧几里得算法求出x和y 之后m = (c1^x*c2^y) mod n 根据结合律可以写成m = ((c1^x mod n)*(c2^y mod n)) mod n


#共模攻击
from Crypto.Util.number import *
import libnum
import gmpy2
n=549785700554963543393222974982211136067042846536450239199968863551137077564447156832697813202963334596948298760762991663065504535035143397250208506445202607659676332816610122258862787906629525548439909792727593939957178783466989816894454522630301104349317697612174888605090061231211194974337772507249418567229560145454791075929946332668360553910328900103264562348881791004831033587660163923517440406942993348972589262051083908075790422096042338651001937740085414301019827335549437397656318095919875053213333008551761167437683250592542156348138055482054331330609375930693247365749085041596578748797801601289693449629548744535914348450016287545136436964138806081283470239420969311905998245715160353982174880912315601876305613349276824998688275587308133069178764001924866079232824850209407236694426779262951463035278887804883917516580169051530590466082511045503107508117656821592538792566264160105940730326929474477787053681516844548383814388361089499629312831727731267796167205124844987064389097138747938870221504684958713047985374714612321540288239995935347905120710583169131356970267386562665138437631517802641426575996558648777831102462652517305151412695166331935115971277205305816897886952646432233312318756155702046584205507027737
e1=3247473589
e2=3698409173
c1=295658788074157816670393593671184451782123605135184996662528766686642109492132533952160456440919197939935742027629210419312032730004032666912404179229952394343569590488768472800784830058534578639706805456277578757250365834591813481786084959844340418320620440636997732915872346619679993987903742079972676425404864295283955565746004124045155664762158516005326368384488346997494926539295740248007606864906884407198601326915643000764477435205579583836917598642053869541648731754384026407310786288997756775232852732033054591953078116290088267188296560877481534143707414153749140670404213262630122369941889862912426176115220410931992046973925991075473656781794097329513119548617920256625579072719981729556158392454956362838720993254919638177786730004086883044525967823454986241038123671907279715773848673713008902432841449556980494600938989397567019338970200872333713986608537678650318511128703055185979834233315117153115613952940778789222515375743186066883492596068186378372611075958909412662251913621375996518671118244409393829141365207153662416265238312206577474940661548038715230313608405518108581922154335405303862701783678336161505643508831482409054761542959278392940037561736468155509922530420964726953308604138731805543997557197893
c2=219454357017359138238563345020257296433275019950745269658921329153689267055871241202626317639487122341365759606018366576305678949982408366815977617307888894995289951707241009621444691307275542686770303994110416384086739599181934011812163156338859395115724413628620575935425221522079154607411877822646179457455118804970038865452163833416447505142114976758532806787419762250921421272492466133659234602794242531776209324085944417173098820895755851386042954303555790085402616519592065446023510096773546730662074307900123349548340507067971393642039476326402523930789953483843698593104578179169624886357604650615249286150367204109726460230037005175927865466199600272190112483494387929732049738312695796015009178606906549093365261114132002222704510637261038978031857378729856467918978246977163353146981239215886053379980533235786905270211605457443266127512667882149285155542735532327780898540341696557860555884277608448996773250847560675650046440569736010800155992053362696097992699863059686881689842065077997427372972290872427656847223849769329713841670853267584161386494525686204330028142217737052411422895042170169703550774908415280261731967511925122636118468176645781785352430657090024109246103061415446942211482659025722233229083093876

#在使用共模攻击之前需要判断e1 e2是否互素
def is_prime(e1,e2):
    flag = gmpy2.gcd(e1,e2)
    if flag == 1:
        print("e1 e2互质")
    else:
        print("e1 e2不互素,需要求取最大公约数!")
    

def exp_def(e1,e2,c1,c2,n):

    s,s1,s2 = gmpy2.gcdext(e1, e2)

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

    return int(m)

is_prime(e1,e2)
m=exp_def(e1,e2,c1,c2,n)
print(libnum.n2s(m))

简单的Python

import time
from tqdm import tqdm
from qsnctf import *



flag = "flag{}"
flag = caesar_encrypt(flag, 8)
for i in tqdm(range(21)):
    flag = string_reverse(flag)
flag = atbash_cipher(flag)
for i in tqdm(range(20)):
    flag = base64_encode(flag)
flag = base100_encode(flag)
print(flag)

# flag = "                                                                                                            "

整个加密的脚本看下来就是进行了:

  1. 凯撒加密。偏移量为8
  2. 接下来就是对字符串进行了21次反转
  3. 进行阿特巴西加密
  4. 20次base64加密
  5. base100解密!
  6. 同时用了自己的一个库!qsnctf

整个解题思路便是倒着先base100,然后经过20次base64,然后进行atbash解密,需要写一个atbash的脚本,继续反转21次,最后carser解密。

#atbash解密

from string import ascii_uppercase,ascii_lowercase

dir_atbash_upper = ascii_uppercase[::-1]
dir_atbash_lower = ascii_lowercase[::-1]

def atbash_cipher(flag:str):
    temp = ''
    for s in flag:
        if s.isupper():
            temp+=''.join(dir_atbash_upper[ascii_uppercase.index(s)])
        elif s.islower():
            temp+=''.join(dir_atbash_lower[ascii_lowercase.index(s)])
        else:
            temp+=''.join(s)
    return temp

[HGAME 2022 week2]RSA Attack2

import re
from math import ceil
from Crypto.Util.number import getPrime
from libnum import s2n
from secret import flag

flag_parts = list(map(s2n, re.findall(rf".{{,{ceil(len(flag) / 3)}}}", flag)))

print("# task1")
m = flag_parts[0]
e = 65537
p = getPrime(1024)
q = getPrime(1024)
r = getPrime(1024)
n1 = p * q
c1 = pow(m, e, n1)
n2 = r * q
c2 = pow(m, e, n2)
print("e =", e)
print("n1 =", n1)
print("c1 =", c1)
print("n2 =", n2)
print("c2 =", c2)

print("# task2")
m = flag_parts[1]
e = 7
p = getPrime(1024)
q = getPrime(1024)
n = p * q
c = pow(m, e, n)
print("e =", e)
print("n =", n)
print("c =", c)

print("# task3")
m = flag_parts[2]
p = getPrime(1024)
q = getPrime(1024)
n = p * q
e1 = getPrime(32)
e2 = getPrime(32)
c1 = pow(m, e1, n)
c2 = pow(m, e2, n)
print("n =", n)
print("e1 =", e1)
print("c1 =", c1)
print("e2 =", e2)
print("c2 =", c2)

整个题目分为三个知识点,利用三个加密方法分别对三部分的flag进行加密:

  1. 普通的RSA,利用了公约数,求解另外的p r素数
  2. 低指数加密攻击
  3. 共享素数攻击

低指数加密攻击:

背景:当e很小的时候,比如说e=3,但是模数n却很大

RSA加密公式为:C=M^e%n

当M^e

当M^e>n的时候,此时用爆破的方法,假设M^e/n的商为k,余数为C,那么M^e=k*n+C,对k进行爆破,只要k满足 kn + C能够开e次方就可以得明文

共享素数攻击:

当题目给予我们多组e(公钥)和c(密文)的时候,他们共用同一个n,并且e1 e2互质的时候,存在gcd(e1,e2)=1,根据扩展的欧几里得算法,一定存在整数x,y使得e1*x+e2*y=1,我们可以通过调用gmpy2.gcdext()来运用欧几里得算法求出x和y 之后m = (c1^x*c2^y) mod n 根据结合律可以写成m = ((c1^x mod n)*(c2^y mod n)) mod n


import re
from math import ceil
from Crypto.Util.number import *
from libnum import s2n
import libnum
import gmpy2

#第一部分利用公约数求解三个素数

def task1_exp():
    e1 = 65537
    n1 = 14611545605107950827581005165327694782823188603151768169731431418361306231114985037775917461433925308054396970809690804073985835376464629860609710292181368600618626590498491850404503443414241455487304448344892337877422465715709154238653505141605904184985311873763495761345722155289457889686019746663293720106874227323699288277794292208957172446523420596391114891559537811029473150123641624108103676516754449492805126642552751278309634846777636042114135990516245907517377320190091400729277307636724890592155256437996566160995456743018225013851937593886086129131351582958811003596445806061492952513851932238563627194553
    c1 = 965075803554932988664271816439183802328812013694203741320763105376036912584995031647672348468111310423680858101990670067065306237596121664884353679987689532305437801346923070145524106271337770666947677115752724993307387122132705797012726237073550669419110046308257408484535063515678066777681017211510981429273346928022971149411064556225001287399141306136081722471075032423079692908380267160214143720516748000734987068685104675254411687005690312116824966036851568223828884335112144637268090397158532937141122654075952730052331573980701136378212002956719295192733955673315234274064519957670199895100508623561838510479
    n2 = 20937478725109983803079185450449616567464596961348727453817249035110047585580142823551289577145958127121586792878509386085178452171112455890429474457797219202827030884262273061334752493496797935346631509806685589179618367453992749753318273834113016237120686880514110415113673431170488958730203963489455418967544128619234394915820392908422974075932751838012185542968842691824203206517795693893863945100661940988455695923511777306566419373394091907349431686646485516325575494902682337518438042711296437513221448397034813099279203955535025939120139680604495486980765910892438284945450733375156933863150808369796830892363
    c2 = 11536506945313747180442473461658912307154460869003392732178457643224057969838224601059836860883718459986003106970375778443725748607085620938787714081321315817144414115589952237492448483438910378865359239575169326116668030463275817609827626048962304593324479546453471881099976644410889657248346038986836461779780183411686260756776711720577053319504691373550107525296560936467435283812493396486678178020292433365898032597027338876045182743492831814175673834198345337514065596396477709839868387265840430322983945906464646824470437783271607499089791869398590557314713094674208261761299894705772513440948139429011425948090

    #公约数为q 利用公约数求p r
    q = gmpy2.gcd(n1,n2)
    p = n1 // q
    r = n2 // q
    phi_1 = (p-1)*(q-1)
    phi_2 = (q-1)*(r-1)
    d1 = libnum.invmod(e1,phi_1)
    d2 = libnum.invmod(e1,phi_2)
    m1 = pow(c1,d1,n1)  #这里可以不用全部都解出来 只解一个就好
    return long_to_bytes(m1)

#低加密指数攻击 
def task2_exp():
    # task2
    k = 0
    e2 = 7
    n = 14157878492255346300993349653813018105991884577529909522555551468374307942096214964604172734381913051273745228293930832314483466922529240958994897697475939867025561348042725919663546949015024693952641936481841552751484604123097148071800416608762258562797116583678332832015617217745966495992049762530373531163821979627361200921544223578170718741348242012164115593777700903954409103110092921578821048933346893212805071682235575813724113978341592885957767377587492202740185970828629767501662195356276862585025913615910839679860669917255271734413865211340126544199760628445054131661484184876679626946360753009512634349537
    c = 10262871020519116406312674685238364023536657841034751572844570983750295909492149101500869806418603732181350082576447594766587572350246675445508931577670158295558641219582729345581697448231116318080456112516700717984731655900726388185866905989088504004805024490513718243036445638662260558477697146032055765285263446084259814560197549018044099935158351931885157616527235283229066145390964094929007056946332051364474528453970904251050605631514869007890625
    while 1:
        res = gmpy2.iroot((k*n+c),e2)
        if res[1]==True:
            m = long_to_bytes(res[0])
            break
        k+=1
    return m

#共享素数攻击
def task3_exp():
    # task3
    n = 18819509188106230363444813350468162056164434642729404632983082518225388069544777374544142317612858448345344137372222988033366528086236635213756227816610865045924357232188768913642158448603346330462535696121739622702200540344105464126695432011739181531217582949804939555720700457350512898322376591813135311921904580338340203569582681889243452495363849558955947124975293736509426400460083981078846138740050634906824438689712748324336878791622676974341814691041262280604277357889892211717124319329666052810029131172229930723477981468761369516771720250571713027972064974999802168017946274736383148001865929719248159075729
    e1 = 2519901323
    c1 = 3230779726225544872531441169009307072073754578761888387983403206364548451496736513905460381907928107310030086346589351105809028599650303539607581407627819797944337398601400510560992462455048451326593993595089800150342999021874734748066692962362650540036002073748766509347649818139304363914083879918929873577706323599628031618641793074018304521243460487551364823299685052518852685706687800209505277426869140051056996242882132616256695188870782634310362973153766698286258946896866396670872451803114280846709572779780558482223393759475999103607704510618332253710503857561025613632592682931552228150171423846203875344870
    e2 = 3676335737
    c2 = 940818595622279161439836719641707846790294650888799822335007385854166736459283129434769062995122371073636785371800857633841379139761091890426137981113087519934854663776695944489430385663011713917022574342380155718317794204988626116362865144125136624722782309455452257758808172415884403909840651554485364309237853885251876941477098008690389600544398998669635962495989736021020715396415375890720335697504837045188626103142204474942751410819466379437091569610294575687793060945525108986660851277475079994466474859114092643797418927645726430175928247476884879817034346652560116597965191204061051401916282814886688467861
    if GCD(e1,e2)==1:
        _,x,y = gmpy2.gcdext(e1,e2)
        m = (pow(c1,x,n)*pow(c2,y,n))%n
        return long_to_bytes(m)
flag1 = task1_exp()
flag2 = task2_exp()
flag3 = task3_exp()

print(flag1+flag2+flag3)

[zer0pts 2020]ROR

import random
from secret import flag
#创建匿名函数
ror = lambda x, l, b: (x >> l) | ((x & ((1<

看一下密文,一共有367行密文,记密文为c,即c1.......c367已知

CTF-Crypto练习_第1张图片


主要的加密代码如下:

for i in range(m.bit_length()):
    print(pow(ror(m, i, m.bit_length()), e, N))

ci = (ror(m,i,m.bit_length()) ^ e)%N 即 ci = k * N + (ror(m,i,m.bit_length()) ^ e) ,ci表示第i次的密文

模数N = 2 ^ randint * (3 ^ randint) * (7 ^ randint),也就是说N是2的倍数即N是一个偶数;众所周知,如果一个数是偶数的话,那么这个数的二进制数最后一位必然是0,反之必然是1;由于N是偶数,那么k*N 必然也是偶数了;那么整体上的ci的奇偶性就取决于ror(m,i,m.bit_length()) ^ e;也就是说:

  1. 当ci的最后一位是 0 那么(ror(m,i,m.bit_length()) ^ e)的最后一位必然就是 0
  2. 当ci的最后一位是 1 那么(ror(m,i,m.bit_length()) ^ e)的最后一位必然就是 1

当i = 0时:ror(m,i,m.bit_length()) ^ e == m| 0 ==m, 所以说c0是偶数的话,那么c0的最后一位就是0 => (ror(m,i,m.bit_length()) ^ e)的最后一位就是0 ,上面刚好推出来 他就是m 那么c0的最后一位就是m的最后一位!

当i=1的时候,ror(m,i,m.bit_length()) ^ e == (m>>1)| (m & 1) << 366 ; 得出结论c1的最后一位就是m的倒数第二位;具体原因如下:

(m&1)<<366 的最后一位必然是0 (低位补0),那么整体(m >>1)| ((m&1)<<366)的最后一位的值取决于m>>1的最后一位也就是m的倒数第二位,所以我们就这样得到了m的倒数第二位,当i为其他值同理

最终给出代码如下:


from Crypto.Util.number import *
f = open("CTF分享\\Crypto-3\\tmp\\chall.txt","rb").readlines()
bits = ''
for line in f:
    tmp = bin(int(line))[2:]  #将每行读取出来的数字转换成二进制 去掉开头的0b
    bits +=tmp[-1] 		#取出每一行的最后一位  也就是m>>i的最后一位
bits = bits[::-1]		#取完之后,整体刚好相反,需要做一下逆置
bits = int(bits,2)		#最终将二进制数 在转换为十进制数

print(long_to_bytes(bits))

整个代码其实不难,难得是分析出加密的过程。

2022强网杯ASR

from Crypto.Util.number import getPrime
from secret import falg
pad = lambda s:s + bytes([(len(s)-1)%16+1]*((len(s)-1)%16+1))

n = getPrime(128)**2 * getPrime(128)**2 * getPrime(128)**2 * getPrime(128)**2
e = 3

flag = pad(flag)
print(flag)
assert(len(flag) >= 48)
m = int.from_bytes(flag,'big')
c = pow(m,e,n)

print(f'n = {n}')
print(f'e = {e}')
print(f'c = {c}')

'''
n = 8250871280281573979365095715711359115372504458973444367083195431861307534563246537364248104106494598081988216584432003199198805753721448450911308558041115465900179230798939615583517756265557814710419157462721793864532239042758808298575522666358352726060578194045804198551989679722201244547561044646931280001
e = 3
c = 945272793717722090962030960824180726576357481511799904903841312265308706852971155205003971821843069272938250385935597609059700446530436381124650731751982419593070224310399320617914955227288662661442416421725698368791013785074809691867988444306279231013360024747585261790352627234450209996422862329513284149
'''

乍一看e比较小,n也比较大,可能会尝试去使用低加密指数攻击(但是会发现e和素数是不互素的,没有那么简单)。 可以看到n=p^2*q^2*r^2*k^2

那么我们可以直接给n开方,开方之后再利用yafu或者在线分解平台进行素数的分解!

import libnum
import gmpy2

n = 8250871280281573979365095715711359115372504458973444367083195431861307534563246537364248104106494598081988216584432003199198805753721448450911308558041115465900179230798939615583517756265557814710419157462721793864532239042758808298575522666358352726060578194045804198551989679722201244547561044646931280001
e = 3
c = 945272793717722090962030960824180726576357481511799904903841312265308706852971155205003971821843069272938250385935597609059700446530436381124650731751982419593070224310399320617914955227288662661442416421725698368791013785074809691867988444306279231013360024747585261790352627234450209996422862329513284149

new_n = gmpy2.iroot(n,2)
print(new_n[0])	#这里将n直接开方 得到了n = p*q*k*r 再拿去进行分解!

CTF-Crypto练习_第2张图片

得到了四个素数!

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

n = 8250871280281573979365095715711359115372504458973444367083195431861307534563246537364248104106494598081988216584432003199198805753721448450911308558041115465900179230798939615583517756265557814710419157462721793864532239042758808298575522666358352726060578194045804198551989679722201244547561044646931280001
e = 3
c = 945272793717722090962030960824180726576357481511799904903841312265308706852971155205003971821843069272938250385935597609059700446530436381124650731751982419593070224310399320617914955227288662661442416421725698368791013785074809691867988444306279231013360024747585261790352627234450209996422862329513284149

new_n = gmpy2.iroot(n,2)
print(new_n[0])
p = 218566259296037866647273372633238739089
q = 223213222467584072959434495118689164399 #q-1 和 e互素
r = 225933944608558304529179430753170813347
k = 260594583349478633632570848336184053653 #k-1 和 e互素 

phi = (q-1)*q*(k-1)*k
n = q**2*k**2
d = gmpy2.invert(e,phi)
m = pow(c,d,n)
print(long_to_bytes(m))

得到的四个素数,其中有两个是和e不互素的,所以这里存在两种方法,一种就是有限域开方。另一种便是重新定义n=q**2*k**2;那么欧拉函数便是 phi = q*(q-1)*k*(k-1),之后便可以求出d;正常求m即可

import gmpy2
#  有限域开方
import libnum

n = 8250871280281573979365095715711359115372504458973444367083195431861307534563246537364248104106494598081988216584432003199198805753721448450911308558041115465900179230798939615583517756265557814710419157462721793864532239042758808298575522666358352726060578194045804198551989679722201244547561044646931280001
e = 3
c = 945272793717722090962030960824180726576357481511799904903841312265308706852971155205003971821843069272938250385935597609059700446530436381124650731751982419593070224310399320617914955227288662661442416421725698368791013785074809691867988444306279231013360024747585261790352627234450209996422862329513284149
p = 218566259296037866647273372633238739089
q = 223213222467584072959434495118689164399 #q-1 和 e互素
r = 225933944608558304529179430753170813347
v = 260594583349478633632570848336184053653 #k-1 和 e互素 
R. = Zmod(p)[]	#这一行的作用是创建一个多项式环,其中的运算是在模 p下进行的。
f = x^e-c	#计算多项式 f(x)=x^e−c的根
f = f.monic()   #将多项式的首项系数规范化为1
res1 = f.roots() #roots用于找到多项式的根。在这里,res1 将包含多项式 f 的所有根的列表。

R. = Zmod(q)[]
f = x^e-c
f = f.monic()
res2 = f.roots()

R. = Zmod(r)[]
f = x^e-c
f = f.monic()
res3 = f.roots()

R. = Zmod(v)[]
f = x^e-c
f = f.monic()
res4 = f.roots()

for i in res1:
    for j in res2:
        for k in res3:
            for z in res4:
            #普通的中国剩余定理
                m = crt([int(i[0]),int(j[0]),int(k[0]),int(z[0])],[p,q,r,v])
                flag = libnum.n2s(int(m))
                if flag.startswith(b'flag'):
                    print(flag)

[HDCTF 2023]Math_Rsa

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


m=bytes_to_long(flag)
r=getPrime(1024)
assert r%4==3
p=getPrime(1024)
assert pow(p,(r-1)//2,r)==1
q=getPrime(1024)
e=65537
n=p*q
a=pow(p,2,r)
c=pow(m,e,n)
print(f"n = {n}")
print(f"r = {r}")
print(f"a = {a}")
print(f"c = {c}")
'''
n = 14859096721972571275113983218934367817755893152876205380485481243331724183921836088288081702352994668073737901001999266644597320501510110156000004121260529706467596723314403262665291609405901413014268847623323618322794733633701355018297180967414569196496398340411723555826597629318524966741762029358820546567319749619243298957600716201084388836601266780686983787343862081546627427588380349419143512429889606408316907950943872684371787773262968532322073585449855893701828146080616188277162144464353498105939650706920663343245426376506714689749161228876988380824497513873436735960950355105802057279581583149036118078489
r = 145491538843334216714386412684012043545621410855800637571278502175614814648745218194962227539529331856802087217944496965842507972546292280972112841086902373612910345469921148426463042254195665018427080500677258981687116985855921771781242636077989465778056018747012467840003841693555272437071000936268768887299
a = 55964525692779548127584763434439890529728374088765597880759713360575037841170692647451851107865577004136603179246290669488558901413896713187831298964947047118465139235438896930729550228171700578741565927677764309135314910544565108363708736408337172674125506890098872891915897539306377840936658277631020650625
c = 12162333845365222333317364738458290101496436746496440837075952494841057738832092422679700884737328562151621948812616422038905426346860411550178061478808128855882459082137077477841624706988356642870940724988156263550796637806555269282505420720558849717265491643392140727605508756229066139493821648882251876933345101043468528015921111395602873356915520599085461538265894970248065772191748271175288506787110428723281590819815819036931155215189564342305674107662339977581410206210870725691314524812137801739246685784657364132180368529788767503223017329025740936590291109954677092128550252945936759891497673970553062223608
'''

 这里的关键是如何利用 a=pow(p,2,r) 来求解出 p;这个是整个问题的关键点!这里需要用到sagemath进行求解!

#sagemath求解p
r = 145491538843334216714386412684012043545621410855800637571278502175614814648745218194962227539529331856802087217944496965842507972546292280972112841086902373612910345469921148426463042254195665018427080500677258981687116985855921771781242636077989465778056018747012467840003841693555272437071000936268768887299
a = 55964525692779548127584763434439890529728374088765597880759713360575037841170692647451851107865577004136603179246290669488558901413896713187831298964947047118465139235438896930729550228171700578741565927677764309135314910544565108363708736408337172674125506890098872891915897539306377840936658277631020650625
R.

=PolynomialRing(Zmod(r)) f=(p^2)-a ans=f.roots() print(ans) #再解释一下 各个参数的含义: #R.

=PolynomialRing(Zmod(r)) 其中的Zmod(r):指定模,定义界限为r的环 Z表示证书; #指定模是划定这个环的界限 有效的数字就是从0到r,其他的都通过与r取模来保证在0~r这个范围内; #Zmod代表这个是一个整数域中的r模环 #ZZ:整数环 QQ:有理数环 RR:实数环 CC:复数环 #R只是一个指针,指向用PolynomialRing指定的那个环(可以用任意字符) #PolynomialRing:这个就是说建立多项式环 #.

:指定一个变量的意思(可以用任意字符) f=(p^2)-a 是定义一个函数f ans=f.roots()是求解f中所有满足函数的自变量

拿到p之后,来验证p*q是否等于n

CTF-Crypto练习_第3张图片

得到了两个p值,所以这里就需要去验证下p*q是否==n

import gmpy2
import libnum
from Crypto.Util.number import *
n = 14859096721972571275113983218934367817755893152876205380485481243331724183921836088288081702352994668073737901001999266644597320501510110156000004121260529706467596723314403262665291609405901413014268847623323618322794733633701355018297180967414569196496398340411723555826597629318524966741762029358820546567319749619243298957600716201084388836601266780686983787343862081546627427588380349419143512429889606408316907950943872684371787773262968532322073585449855893701828146080616188277162144464353498105939650706920663343245426376506714689749161228876988380824497513873436735960950355105802057279581583149036118078489
r = 145491538843334216714386412684012043545621410855800637571278502175614814648745218194962227539529331856802087217944496965842507972546292280972112841086902373612910345469921148426463042254195665018427080500677258981687116985855921771781242636077989465778056018747012467840003841693555272437071000936268768887299
a = 55964525692779548127584763434439890529728374088765597880759713360575037841170692647451851107865577004136603179246290669488558901413896713187831298964947047118465139235438896930729550228171700578741565927677764309135314910544565108363708736408337172674125506890098872891915897539306377840936658277631020650625
c = 12162333845365222333317364738458290101496436746496440837075952494841057738832092422679700884737328562151621948812616422038905426346860411550178061478808128855882459082137077477841624706988356642870940724988156263550796637806555269282505420720558849717265491643392140727605508756229066139493821648882251876933345101043468528015921111395602873356915520599085461538265894970248065772191748271175288506787110428723281590819815819036931155215189564342305674107662339977581410206210870725691314524812137801739246685784657364132180368529788767503223017329025740936590291109954677092128550252945936759891497673970553062223608

q1 = 135098300162574110032318082604507116145598393187097375349178563291884099917465443655846455456198422625358836544141120445250413758672683505731015242196083913722084539762488109001442453793004455466844129788221721833309756439196036660458760461237225684006072689852654273913614912604470081753828559417535710077291
q2 = 10393238680760106682068330079504927400023017668703262222099938883730714731279774539115772083330909231443250673803376520592094213873608775241097598890818459890825805707433039425020588461191209551582950712455537148377360546659885111322482174840763781771983328894358193926388929089085190683242441518733058810008
print(isPrime(q1))
print(isPrime(q2))  #发现其中的q2 并不是素数,那么确定了q = q1
e=65537
p = n//q1
if p*q1==n:
    phi = (p-1)*(q1-1)
    d = gmpy2.invert(e,phi)
    m = pow(c,d,n)
    result = long_to_bytes(m)
    print(result)

你可能感兴趣的:(CTF,安全,web安全,网络,网络安全,学习)