NewStar2024-week2-Crypto
Crypto
茶里茶气
from Crypto.Util.number import *
flag = "flag{*****}"
assert len( flag ) == 25
a = ""
for i in flag:
a += hex(ord(i))[2:]
l = int(a,16).bit_length()
print("l =" , l )
v0 = int(a,16)>>(l//2)
v1 = int(a,16)-(v0<<(l//2))
p = getPrime(l//2+10)
v2 = 0
derta = 462861781278454071588539315363
v3 = 489552116384728571199414424951
v4 = 469728069391226765421086670817
v5 = 564098252372959621721124077407
v6 = 335640247620454039831329381071
assert v1 < p and v0 < p and derta < p and v3 < p and v4 < p and v5 < p and v6 < p
for i in range(32):
v1 += (v0+v2) ^ ( 8*v0 + v3 ) ^ ( (v0>>7) + v4 ) ; v1 %= p
v0 += (v1+v2) ^ ( 8*v1 + v5 ) ^ ( (v1>>7) + v6 ) ; v0 %= p
v2 += derta ; v2 %= p
print( "p =" , p )
print( "v0 =" , v0 )
print( "v1 =" , v1 )
很简单的加密,解密和加密过程基本对称。
我直接尝试丢给ai(chatgpt-4o),主要就是引导它分析出这类似于tea加密,然后它就可以解了。
def decrypt(v0, v1, p, derta, v3, v4, v5, v6):
v2 = (derta * 32) % p # 还原v2初始值,32轮操作
# 逆序执行32轮加密过程
for i in range(32):
v2 = (v2 - derta) % p
v0 = (v0 - ((v1+v2) ^ (8*v1 + v5) ^ ((v1>>7) + v6))) % p
v1 = (v1 - ((v0+v2) ^ (8*v0 + v3) ^ ((v0>>7) + v4))) % p
return v0, v1
# 已知加密后的v0和v1
v0 = 190997821330413928409069858571234
v1 = 137340509740671759939138452113480
# 质数p,常数derta和其他加密常量
p = 446302455051275584229157195942211
derta = 462861781278454071588539315363
v3 = 489552116384728571199414424951
v4 = 469728069391226765421086670817
v5 = 564098252372959621721124077407
v6 = 335640247620454039831329381071
# 解密得到原始的v0和v1
v0_dec, v1_dec = decrypt(v0, v1, p, derta, v3, v4, v5, v6)
print("Decrypted v0:", v0_dec)
print("Decrypted v1:", v1_dec)
# 计算位长
l = 199 # 由加密输出的位长
# 还原大整数
a_dec = (v0_dec << (l // 2)) + v1_dec
# 转回16进制
hex_str = hex(a_dec)[2:]
# 转换为字符
flag = ''.join([chr(int(hex_str[i:i+2], 16)) for i in range(0, len(hex_str), 2)])
print("Decrypted flag:", flag)
"""
Decrypted v0: 1014351839000028912764735400942
Decrypted v1: 348231531876293114407512127357
Decrypted flag: flag{f14gg9_te2_1i_7ea_7}
"""
just one and more than two
from Crypto.Util.number import *
flag = b'flag{?????}'
m1 = bytes_to_long(flag[:len(flag)//2])
m2 = bytes_to_long(flag[len(flag)//2:])
e = 65537
p, q, r= (getPrime(512) for _ in range(3))
N=p*q*r
c1 = pow(m1, e, p)
c2 = pow(m2, e, N)
print(f'p={p}\nq={q}\nr={r}\nc1={c1}\nc2={c2}')
m1和m2都比p小,都用p就行了
from Crypto.Util.number import *
p=11867061353246233251584761575576071264056514705066766922825303434965272105673287382545586304271607224747442087588050625742380204503331976589883604074235133
q=11873178589368883675890917699819207736397010385081364225879431054112944129299850257938753554259645705535337054802699202512825107090843889676443867510412393
r=12897499208983423232868869100223973634537663127759671894357936868650239679942565058234189535395732577137079689110541612150759420022709417457551292448732371
c1=8705739659634329013157482960027934795454950884941966136315983526808527784650002967954059125075894300750418062742140200130188545338806355927273170470295451
c2=1004454248332792626131205259568148422136121342421144637194771487691844257449866491626726822289975189661332527496380578001514976911349965774838476334431923162269315555654716024616432373992288127966016197043606785386738961886826177232627159894038652924267065612922880048963182518107479487219900530746076603182269336917003411508524223257315597473638623530380492690984112891827897831400759409394315311767776323920195436460284244090970865474530727893555217020636612445
print(long_to_bytes(pow(c1,inverse(65537,p-1),p))+long_to_bytes(pow(c2,inverse(65537,p-1),p)))
#b'flag{Y0u_re4lly_kn0w_Euler_4nd_N3xt_Eu1er_is_Y0u!}'
这是几次方? 疑惑!
from Crypto.Util.number import *
flag = b'flag{*****}'
p = getPrime(512)
q = getPrime(512)
n = p*q
e = 65537
m = bytes_to_long(flag)
c = pow(m, e, n)
hint = p^e + 10086
print("c =", c)
print("[n, e] =", [n, e])
print("hint =", hint)
加法优先级大于异或运算
from Crypto.Util.number import *
c = 36513006092776816463005807690891878445084897511693065366878424579653926750135820835708001956534802873403195178517427725389634058598049226914694122804888321427912070308432512908833529417531492965615348806470164107231108504308584954154513331333004804817854315094324454847081460199485733298227480134551273155762
[n, e] = [124455847177872829086850368685666872009698526875425204001499218854100257535484730033567552600005229013042351828575037023159889870271253559515001300645102569745482135768148755333759957370341658601268473878114399708702841974488367343570414404038862892863275173656133199924484523427712604601606674219929087411261, 65537]
hint = 12578819356802034679792891975754306960297043516674290901441811200649679289740456805726985390445432800908006773857670255951581884098015799603908242531673390
p=hint^(e+10086)
print(long_to_bytes(pow(c,inverse(e,p-1),p)))
#b'flag{yihuo_yuan_lai_xian_ji_suan_liang_bian_de2333}'
Since you konw something
from pwn import xor
#The Python pwntools library has a convenient xor() function that can XOR together data of different types and lengths
from Crypto.Util.number import bytes_to_long
key = ?? #extremely short
FLAG = 'flag{????????}'
c = bytes_to_long(xor(FLAG,key))
print("c={}".format(c))
'''
c=218950457292639210021937048771508243745941011391746420225459726647571
'''
直接爆破即可。
(不能直接整数进行异或,整数不让超过255,需要转成字节后pwntools里的xor函数才能达成想要的效果)
from pwn import xor
from Crypto.Util.number import long_to_bytes
c=218950457292639210021937048771508243745941011391746420225459726647571
c=long_to_bytes(c).decode()
key=0
while True:
tmp=long_to_bytes(key)
flag=xor(c,tmp)
if b'flag' in flag:
print(flag)
break
key=key+1
#b'flag{Y0u_kn0w_th3_X0r_b3tt3r}'