from Crypto.Util.number import *
from Crypto.Cipher import AES
from hashlib import sha256
from random import randbytes, getrandbits
from flag import flag
def diffie_hellman(g, p, flag):
alice = getrandbits(1024)
bob = getrandbits(1024)
alice_c = pow(g, alice, p)
bob_c = pow(g, bob, p)
print(alice_c , bob_c)
key = sha256(long_to_bytes(pow(bob_c, alice, p))).digest()
iv = b"dasctfdasctfdasc"
aes = AES.new(key, AES.MODE_CBC, iv)
enc = aes.encrypt(flag)
print(enc)
def getp():
p = int(input("P = "))
assert isPrime(p)
assert p.bit_length() >= 1024 and p.bit_length() <= 2048
g = 2
diffie_hellman(g, p, flag)
getp()
diffie-hellman,p选手给,那就构造一个p-1光滑直接梭哈掉了。
exp:
import gmpy2
from Crypto.Util.number import getPrime
import random
from Crypto.Util.number import *
from Crypto.Cipher import AES
from hashlib import sha256
def gen_prime(digit):
primes = []
pri = 1
while(len(primes)<100):
pri = gmpy2.next_prime(pri)
primes.append(int(pri))
while True:
count = 2
while count < 2**digit:
count *= random.choice(primes)
count += 1
if(gmpy2.is_prime(count)):
return count
'''p = gen_prime(1024)
G = GF(P)
g_ = G(g)
ac_ = G(ac)
alice = int(discrete_log(ac_,g_))
print(alice)
'''
alice = 1046382552755992811457982912694618414872058936337177684338202569822370210620216903105219207397545099396117900950990663819206744964944899595012911402477464329708104871889963814612755420606417426402402131901720127104652472541002317267138113556214527301245557009631475388100000836750737255081835356782751153367
P = 335347423405170083398559193700458873250569626299973646883438047064926777811449508027635784322795263459385528095096950146720369849218673184537518905837461553332860863341898712720955258188662619459370538150944015362912381662926695555870098124952507918358330303676192552193204581458968503798256226692794489522821
ac,bc=223676019829477985645895853282768682560855850770933122577933519525057883850366435365443483994163940231382663968887215078379264068697081085889130204146863047561895606804119130512046059900944330438737166140524383141720020490696090144841644182519896300804491684305301848398654866801293171153005854449806177065769, 175861293669891528934345252748997792066936662405310572915942032646583833324927754007720831902026700146884820356166597766296538489029268404074802240969314519015975193008206638659010499894115919252744649609865797973520881153393357369190942129525709128275570322882970502645366664567710272801953146630381233539658
ct = b'a\\x01\\xe1\\x0f\\x03\\xdd\\xb2\\x88wn\\xear\\xac&\\xbf\\x8aP\\xb1\\xc3C\\xc6\\xfb\\xe1\\xfa\\x8b\\x98\\xc9\\xee;B\\xef\\x19y\\xc2\\x1c\\xfb!\\x16\\xdd/f\\x82+f\\x81\\xee;\\x16'
g = 2
key = sha256(long_to_bytes(pow(bc, alice, P))).digest()
iv = b"dasctfdasctfdasc"
aes = AES.new(key, AES.MODE_CBC, iv)
enc = aes.decrypt(ct)
print(enc)
import gmpy2
from Crypto.Util.number import getPrime
import random
from Crypto.Util.number import *
from Crypto.Cipher import AES
from hashlib import sha256
def gen_prime(digit):
primes = []
pri = 1
while(len(primes)<100):
pri = gmpy2.next_prime(pri)
primes.append(int(pri))
while True:
count = 2
while count < 2**digit:
count *= random.choice(primes)
count += 1
if(gmpy2.is_prime(count)):
return count
'''p = gen_prime(1024)
G = GF(P)
g_ = G(g)
ac_ = G(ac)
alice = int(discrete_log(ac_,g_))
print(alice)
'''
alice = 1046382552755992811457982912694618414872058936337177684338202569822370210620216903105219207397545099396117900950990663819206744964944899595012911402477464329708104871889963814612755420606417426402402131901720127104652472541002317267138113556214527301245557009631475388100000836750737255081835356782751153367
P = 335347423405170083398559193700458873250569626299973646883438047064926777811449508027635784322795263459385528095096950146720369849218673184537518905837461553332860863341898712720955258188662619459370538150944015362912381662926695555870098124952507918358330303676192552193204581458968503798256226692794489522821
ac,bc=223676019829477985645895853282768682560855850770933122577933519525057883850366435365443483994163940231382663968887215078379264068697081085889130204146863047561895606804119130512046059900944330438737166140524383141720020490696090144841644182519896300804491684305301848398654866801293171153005854449806177065769, 175861293669891528934345252748997792066936662405310572915942032646583833324927754007720831902026700146884820356166597766296538489029268404074802240969314519015975193008206638659010499894115919252744649609865797973520881153393357369190942129525709128275570322882970502645366664567710272801953146630381233539658
ct = b'a\\x01\\xe1\\x0f\\x03\\xdd\\xb2\\x88wn\\xear\\xac&\\xbf\\x8aP\\xb1\\xc3C\\xc6\\xfb\\xe1\\xfa\\x8b\\x98\\xc9\\xee;B\\xef\\x19y\\xc2\\x1c\\xfb!\\x16\\xdd/f\\x82+f\\x81\\xee;\\x16'
g = 2
key = sha256(long_to_bytes(pow(bc, alice, P))).digest()
iv = b"dasctfdasctfdasc"
aes = AES.new(key, AES.MODE_CBC, iv)
enc = aes.decrypt(ct)
print(enc)
from Crypto.Util.number import *
from secret import secret, flag
def encrypt(m):
return pow(m, e, n)
assert flag == b"dasctf{" + secret + b"}"
e = 11
p = getPrime(512)
q = getPrime(512)
n = p * q
P = getPrime(512)
Q = getPrime(512)
N = P * Q
gift = P ^ (Q >> 16)
print(N, gift, pow(n, e, N))
print(encrypt(bytes_to_long(secret)),
encrypt(bytes_to_long(flag)))
# 75000029602085996700582008490482326525611947919932949726582734167668021800854674616074297109962078048435714672088452939300776268788888016125632084529419230038436738761550906906671010312930801751000022200360857089338231002088730471277277319253053479367509575754258003761447489654232217266317081318035524086377 8006730615575401350470175601463518481685396114003290299131469001242636369747855817476589805833427855228149768949773065563676033514362512835553274555294034 14183763184495367653522884147951054630177015952745593358354098952173965560488104213517563098676028516541915855754066719475487503348914181674929072472238449853082118064823835322313680705889432313419976738694317594843046001448855575986413338142129464525633835911168202553914150009081557835620953018542067857943
# 69307306970629523181683439240748426263979206546157895088924929426911355406769672385984829784804673821643976780928024209092360092670457978154309402591145689825571209515868435608753923870043647892816574684663993415796465074027369407799009929334083395577490711236614662941070610575313972839165233651342137645009 46997465834324781573963709865566777091686340553483507705539161842460528999282057880362259416654012854237739527277448599755805614622531827257136959664035098209206110290879482726083191005164961200125296999449598766201435057091624225218351537278712880859703730566080874333989361396420522357001928540408351500991
rsa异或的题以前遇到过,这里改成了右移然后异或,改下脚本就OK
import gmpy2 as gp
from tqdm import tqdm
N,gift,c1 = 75000029602085996700582008490482326525611947919932949726582734167668021800854674616074297109962078048435714672088452939300776268788888016125632084529419230038436738761550906906671010312930801751000022200360857089338231002088730471277277319253053479367509575754258003761447489654232217266317081318035524086377,8006730615575401350470175601463518481685396114003290299131469001242636369747855817476589805833427855228149768949773065563676033514362512835553274555294034,14183763184495367653522884147951054630177015952745593358354098952173965560488104213517563098676028516541915855754066719475487503348914181674929072472238449853082118064823835322313680705889432313419976738694317594843046001448855575986413338142129464525633835911168202553914150009081557835620953018542067857943
P_h = gift >> (512-16)
def findp(p,q,q_):
if len(p)==(512-16):
pp=int(p,2) + P_h * 2 ** (512-16)
if gp.gcd(N,pp) > 1:
print(pp)
else:
l=len(p)
pp=int(p,2)
qq=int(q,2)
if (pp^qq)%(2**l)==gift%(2**l) and pp*(qq*2**16 + q_)%(2**l)==N%(2**l):
findp('1'+p,'1'+q,q_)
findp('1'+p,'0'+q,q_)
findp('0'+p,'1'+q,q_)
findp('0'+p,'0'+q,q_)
for q_ in tqdm(range(2**16)):
findp('1','1',q_)
同时注意到一个问题,factordb分一下n,会发现有小因子(甚至是偶数),所以所以n应该比N大,再加一个N查,就啥也查不到了。
后面的就不会了,没做过这种related-message attack,现翻ctf-wiki:
同时flag的长度也不知道,需要爆破:
exp:
from Crypto.Util.number import *
n = 83410392685813224685786027640778560521035854332627839979281105731457044069408118952629284089869335506983096270269822559619624906180108256504440296527471536363057103101146262613593336072556587341466840510200003498265457285439149541137127199088938421905041387224795918868443175561632999479925818053898100117419
c1 = 69307306970629523181683439240748426263979206546157895088924929426911355406769672385984829784804673821643976780928024209092360092670457978154309402591145689825571209515868435608753923870043647892816574684663993415796465074027369407799009929334083395577490711236614662941070610575313972839165233651342137645009
c2 = 46997465834324781573963709865566777091686340553483507705539161842460528999282057880362259416654012854237739527277448599755805614622531827257136959664035098209206110290879482726083191005164961200125296999449598766201435057091624225218351537278712880859703730566080874333989361396420522357001928540408351500991
def attack(c1, c2, e, n,le,h):
PR.<x>=PolynomialRing(Zmod(n))
g1 = x^e - c1
g2 = (h*2^(le+8)+x*2^8+125)^e - c2
def gcd(g1, g2):
while g2:
g1, g2 = g2, g1 % g2
return g1.monic()
return -gcd(g1, g2)[0]
e=11
h = b"dasctf{"
b = b'}'
h = bytes_to_long(h)
b = bytes_to_long(b)
print(b)
for le in range(1,300):
try:
t = attack(c1,c2,e,n,le,h)
print(long_to_bytes(int(t)).decode())
except:
continue