2023SWPU招新

Caesar_base

base64换表,赛博厨子可以直接做,不需要写代码

EasyRSA

p和q已知,正常求解RSA就行

1
2
3
4
5
6
7
8
9
from Crypto.Util.number import *
import gmpy2
p = 122912801126049869009003839542545176400185213365268209105714006257803073428638629824801261702125287814910668428403367391355051987389837804474055637991864563803834741161217607848968821280710324766558457056004037592628178078680121173634128054936108782807954132605887275556228703383455969903056759874047110115433
q = 120790113700754477830062212762518406876786376726996249661848284428829412089402183812692045970711341815805796005449714738748110749559462448861357011272792817313060401380148108517705435100103533857957024851181447994572972501120774586405811257420853542417275740953525627232008812587423053626515513859653865873671
e = 65537
c = 7094224488947659163318199615533819770556597977720767621640224798887506152292861133457571683713587909779712343346370719403811813233693263526316785431883833118583425528830238629831001255198236686372518770451273159769779374149881346761523688131115323441973953523582174059584087249568245044443295176738493785560215046375056269378223045128094953923926250055718405799885041115025529297362914403732661935017257507786348635366480744933193471899621592092711962814949533564454932121056035003021428158830645604347966849572981124877683317022116903132719663958775850982016292384237647664448371811915879714093710876989697939277005
d = gmpy2.invert(e, (p-1)*(q-1))
m = pow(c, d, p*q)
print(long_to_bytes(m))

dpdp

dp泄露,在小于e的范围爆破求p

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
from Crypto.Util.number import *
import gmpy2


n = 62950660589752377241535942010457460675378335694404721223426371627802159493655570041534480026979837056215567303530448462076388942749116962945931432723672826148999814815864738069663127706046027850586024555861960247057288826014343547293035737544457656904257388300461848219257240252715837662741274235378360898441
c = 26392919777656338278184497106215581599692023606797351841011065350738534402079717897589592521000832026751736045905247050532819571969784687491977953157313304550096179520376626220816081159472339787295872214912587497324709488986746768994907107727184468228540635002062232484115731701648311946527233449512543132274
dp = 7088497034630351463006975624795947102639056977565074157092915907376477955247769847204254053775159112398217033648894620506901638351932922911273150932128973
e = 65537
for i in range(1, 65535):
p = (dp * e - 1) // i + 1
if n % p == 0:
q = n // p
break
print(p)
print(q)
phi_n = (p - 1) * (q - 1)
d = gmpy2.invert(e, phi_n)
m = pow(c, d, n)
flag = long_to_bytes(int(m))
print(flag)

close

p和q相差较近,采用费马分解求p和q,然后就是正常求解rsa

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
from Crypto.Util.number import *
import gmpy2
n = 24981376790941538042242194741227892897407513396986731688877133454927442860995432316502739082570143505514748189761926835267759902439088795405888334103808204493954060044146586606969762154041793765844462081845490598211667272961234605967919438875499785814549051002289336390400088945736443426364361032870741024016549739096474413537901098157940458928277363388694717514323106251487767419607466664175936942972759711506228656400164583540573319572125036265662330306877811831045019686459493451558882811173136631573392182233161484350878695026357462290962322316959710815852914274474767115283825849610223430527125542218326259388501
e = 65537
c = 20159395346151098135636315342962498279920000537186367678734614295342297238729946157173169398141183795295342421626812913110784320710149318393656661582157610182569479131625808166266400522513050071081253869746865806961410702124426021839786686971490883603141916263075756918270160269956469968815381434371042453456185750940323619568741956243054983302281739844073931738335165924679149156513059772597287311150001080524533236565521881558592378167621577532597521749930820990533120461791013359786254216859344006298715497621642857727174896969485816794718062289736382736417151820935214824518306312811267158057425922650562544599188


def fermat(n, d):
while 1:
x = int(gmpy2.iroot(n, 2)[0]) + d
y_2 = x * x - n
if gmpy2.iroot(y_2, 2)[1]:
print("第一个因子为")
print(x + int(gmpy2.iroot(y_2, 2)[0]))
p = x + int(gmpy2.iroot(y_2, 2)[0])
print("第二个因子为")
print(x - int(gmpy2.iroot(y_2, 2)[0]))
q = x - int(gmpy2.iroot(y_2, 2)[0])
print("")
break
d = d + 1
return p, q


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

Classical Cipher

先rabbit解密(无密钥),然后栅栏加密(栏数为5),最后base解密

polynomial

在modp上求解多项式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
from Crypto.Util.number import *
p = 158805288384650271811274620112885426807134870587281058486409657841571541118874370262125616758392586636436387032461169543181918821693975663497124408432536495676514953509756505781488235396628730376794651046582155886825258656047349260441547239700695773934518441411466809921946609164932234396841476405798428700843
a = 6782997653971692606019358747667066963688636909392719204001155907616272998599567932030340899158310591583056298423803386927289244122405887173827359025095219
b = 7373784501270128110088353737302182289453185058537147667058852830178883492374394182313086562761123093282613985656842374554466162992585768060168515936322837
c = 12604317328077074383094898759023155531982085126299017370476099122695860476733267706510100804874716354025394150676456477445303955715981977583036765619931291
d = 8651550199315105291497863570314512750737000678752642987669418859342691686702373116147125246177399639155277789016646392989483699799276013474039473014389069
e = 6819653219987864110332165353640553980353581969662542365282269257622467162685937603557862048653003559950780009596692439320585574228684924030626160305559221
y = 187626421635118933741196210961559541641107643327742932086152135660947241144749750951157691964883138108211067837818748515766812840026814947057023367814232867155997328882540000727585104081833734697954005690818776434169815240704563337
h = 36198427687223295973782557044383345640934859884880641150183916728479006412929786917944908958646498915497129126843345300628359


ZmodN = Zmod(p)
P.<x> = PolynomialRing(ZmodN)
f = a*x^4 + b*x^3 + c*x^2 + d*x + e - y
f = f.monic()
x0 = f.small_roots(X=2^64, beta=0.4)[0]
print(x0)
m = h//x0
print(long_to_bytes(int(m)))

肮脏的base64

爆破压缩包密码为CTF,然后写脚本看缺少的字符,摆列组合查出所有字母表的情况

然后解密base64

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# 肮脏的base64
title = '0123456789qwertyuiopasdfghjklzxcvbnm+QWERTYUIOPASDFGHJKLZXCVBNM/'
c = 'o57gjn0Sb9ETqVLYOJyHX42kNaIhrWlU****eszCfD+dtPm1u3AMKpwRGvcxQZ8B'
for i in title:
if i in c:
continue
else:
print(i)
import itertools

characters = "6iF/"
permutations = list(itertools.permutations(characters))
n = []
for perm in permutations:
s = ''.join(perm)
n.append(s)
aph = []
for i in n:
temp = c
aph.append(temp.replace("****",i))
# print(aph)
for i in aph:
print(i)
import string

def base64_decode(data, alphabet):
# 构建解码映射表
decoding_table = {}
for i, char in enumerate(alphabet):
decoding_table[char] = i

# 解码数据
decoded_data = bytearray()
padded_length = len(data) + (4 - len(data) % 4) if len(data) % 4 != 0 else len(data)
padding = alphabet[-1] * (padded_length - len(data))
data += padding

value = 0
count = 0
for char in data:
if char not in decoding_table:
continue
value = (value << 6) | decoding_table[char]
count += 1
if count == 4:
decoded_data.extend([(value >> 16) & 0xFF, (value >> 8) & 0xFF, value & 0xFF])
count = 0
value = 0

return bytes(decoded_data.rstrip(b'\x00'))



# 要解码的 Base64 数据
encoded_data = "HsVHOpJ0lpW9yK4akKWDWe4UW4ZKI0sMkwN3N2WZ"

# 解码数据
for i in aph:
decoded_data = base64_decode(encoded_data, i)

print(decoded_data.decode())

dpdpdpdp

dp泄露,但是e比较大的情况

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from Crypto.Util.number import *
import gmpy2

n = 92288362151232755164303382554034496430634785857894506752180261103500715219090974532177552845107426542175470207920267802066773828210866572070045093611090322738109527534622730588618668861998969946471756352024368486322527057077613762697792913167023012077178671066981439295386486943067698150993422039585259179729
e = 229991316986730339421575788374847647237
c = 66178170892880340054212366602556925884485962775832591797127163461420023986798822926684824340567060840259672460835004142425374706821346941926520921852009455818529825976414766339170445233789109526300838535719649346266975388774091834431039678689254534566870194580604694419819400454951059125553501095973278807456
dp = 8987556601717285362487353965045062789633142861774364363374961991445049127918653163458814169532860957264061203394944931114888144611267605606197232438332289

p = gmpy2.gcd(n, pow(2, dp*e, n)-2)
q = n//p
assert p*q == n
phi = (p-1)*(q-1)
d = gmpy2.invert(e, phi)
m = pow(c, d, n)
print(long_to_bytes(m))

小明文?

相关信息攻击,构造两个多项式求解x

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
from Crypto.Util.number import *
def franklinReiter(n,e,c1,c2):
R.<x> = Zmod(n)[]
f1 = x^e - c1
f2 = (a*x+b)^e- c2
# coefficient 0 = -m, which is what we wanted!
return Integer(n-(compositeModulusGCD(f1,f2)).coefficients()[0])

# GCD is not implemented for rings over composite modulus in Sage
# so we do our own implementation. Its the exact same as standard GCD, but with
# the polynomials monic representation
def compositeModulusGCD(a, b):
if(b == 0):
return a.monic()
else:
return compositeModulusGCD(b, a % b)

n = 13026126941826887019162872735099540876106694302074884925200107036130428843197729140372377590706535217469477301361486550282890330093772372813532795303163348233096919179478061917423707929667355386062657434467799360617526194768968700908096844475960205671302377364202483195391706116078632202015938962280529309403244885363904094804118278167720593581764017089021116316636464533785051436622916960956665030100255641288863474938703
a = 280807370135687531454416708417179457159
b = 210598260561987226227971066630761929397
c1 = 5484670538103757119990644460454986219076673914082966464351809153114702100411054106785392646801736865489738145857425179185164710603704198643749378051371008266521829572436350080663825339915763509501690398283916091505443322384568973565599179112299853287766734493187659418383619877040013434926843623979979122417950089001830664273269598688130410251828579862218274297572192961909808728768317567218412746711665911495028223620671
c2 = 249587944874112168607313602465869274336587750392364868939732783502223999305089384749508572630699199927194600499968110646290832205640569694933539973256281796631433129626712361622584048439446364992886884217198680921278383770604919381329363647924261642857483728973331091285820401689502291336332199019252649615680893389557508558362194551939434128389351824194393680744241807605416750291337127085044177563509645273228457253193
e=5
result = franklinReiter(n,e,c1,c2)
flag = long_to_bytes(int(result))
print(flag)