from Crypto.Util.number import * from secret import flag
M = 0x7cda79f57f60a9b65478052f383ad7dadb714b4f4ac069997c7ff23d34d075fca08fdf20f95fbc5f0a981d65c3a3ee7ff74d769da52e948d6b0270dd736ef61fa99a54f80fb22091b055885dc22b9f17562778dfb2aeac87f51de339f71731d207c0af3244d35129feba028a48402247f4ba1d2b6d0755baff6
defgetMyprime(BIT): whileTrue: p = int(pow(65537, getRandomRange(M>>1, M), M)) + getRandomInteger(BIT-int(M).bit_length()) * M if isPrime(p): return p
p = getMyprime(1024) q = getPrime(1024) n = p * q m = bytes_to_long(flag)
print("Try to crack the bad RSA") print("Public key:", n) print("The flag(encrypted):", pow(m, 65537, n)) print("Well well, I will give you the hint if you please me ^_^") leak = int(input("Gift window:")) if M % leak == 0: print("This is the gift for you: ", p % leak) else: print("I don't like this gift!")
第一眼看这个p的生成方式,以及M,就以为是roca。
尝试了很久用roca来分解n,并没成功
看到$hint \equiv p \mod leak$,这个$leak$是$M$的因子,M是前126个素数之积(无所谓),直接把M进去
得到$hint \equiv p \mod M$
$\therefore p = hint + KM$,这里得到的$hint=971bit$,$M=971bit$,所以$k$大概只有$53bit$
#sage from Crypto.Util.number import * import gmpy2
hint= M = 19467773070115377343221509599623925236459751278180415885837207534756855405403128279156705968461708578168638327032034542684864920135818987044810141311008655898015207220772515212093850725541003213054560185603695585660265284153421684796257245143362498012760214539505870197264858636122745485373430 n = c = e = 65537
R.<k> = PolynomialRing(Zmod(n))
f = k*M + hint f = f.monic() roots = f.small_roots(X = 2^55,beta = 0.4)
#print(roots) p = int(roots[0])*M + hint q = n // p d = gmpy2.invert(e,(p-1)*(q-1)) m = pow(c,d,n) print(long_to_bytes(int(m)))
from Crypto.Util.number import * from Crypto.Cipher import AES from hashlib import md5 from sympy import isprime from tqdm import tqdm import random
flag = b"***********************************" defpad(message): return message + b"\x00"*((16-len(message)%16)%16)
defmyfastexp(m,d,N,j,N_): A = 1 d = bin(d)[2:] n = len(d) for i inrange(n-1,-1,-1): if i < j: #print(A) N = N_ A = A*A % N if d[i] == "1": A = A * m % N return A
defencrypt(message,key): key = bytes.fromhex(md5(str(key).encode()).hexdigest()) enc = AES.new(key,mode=AES.MODE_ECB) c = enc.encrypt(pad(message)) return c
border = "|" print(border*75) print(border, "Hi all, I have created an algorithm that can quickly calculate powers. ", border) print(border, "But it looks like there's something wrong with it. Your task is to get ", border) print(border, "its private key,and decrypt the cipher to cat the flag ^-^ ", border) print(border*75)
whileTrue: # generate p = getPrime(512) q = getPrime(512) n = p*q e = 17 if GCD(e,(p-1)*(q-1)) == 1: d = inverse(e,(p-1)*(q-1)) n_ = n break
msg = bytes_to_long(b"Welcome_come_to_WMCTF") sig = pow(msg,d,n)
CHANGE = True whileTrue: try: ans = input("| Options: \n|\t[G]et data \n|\t[S]ignatrue \n|\t[F]ault injection \n|\t[Q]uit\n").lower().strip() if ans == 'f': if CHANGE: print(border,"You have one chance to change one byte of N. ") temp,index = input("bytes, and index:").strip().split(",") assert0<= int(temp) <=255 assert0<= int(index) <= 1023 n_ = n ^ (int(temp)<<int(index)) print(border,f"[+] update: n_ -> \"{n_}\"") CHANGE = False else: print(border,"Greedy...") elif ans == 'g': print(border,f"n = {n}") print(border,f"flag_ciphertext = {encrypt(flag,d).hex()}") elif ans == 's': index = input("Where your want to interfere:").strip() sig_ = myfastexp(msg,d,n,int(index),n_) print(border,f"signature of \"Welcome_come_to_WMCTF\" is {sig_}") elif ans == 'q': quit() except Exception as e: print(border,"Err...") quit()
from Crypto.Util.number import * from Crypto.Cipher import AES from hashlib import md5 import random
flag = b"***********************************" defpad(message): return message + b"\x00"*((16-len(message)%16)%16)
defmyfastexp(m,d,N,j,N_): A = 1 B = m d = bin(d)[2:][::-1] n = len(d) N = N for i inrange(n): if d[i] == '1': A = A * B % N # a fault occurs j steps before the end of the exponentiation if i >= n-1-j: N = N_ B = B**2 % N return A
defencrypt(message,key): key = bytes.fromhex(md5(str(key).encode()).hexdigest()) enc = AES.new(key,mode=AES.MODE_ECB) c = enc.encrypt(pad(message)) return c
border = "|" print(border*75) print(border, "Hi all, I have another algorithm that can quickly calculate powers. ", border) print(border, "But still there's something wrong with it. Your task is to get ", border) print(border, "its private key,and decrypt the cipher to cat the flag ^-^ ", border) print(border*75)
whileTrue: # generate p = getPrime(512) q = getPrime(512) n = p*q e = 17 if GCD(e,(p-1)*(q-1)) == 1: d = inverse(e,(p-1)*(q-1)) n_ = n break n_ = n msg = bytes_to_long(b"Welcome_come_to_WMCTF") sig = pow(msg,d,n) assert sig == myfastexp(msg,d,n,0,n_) CHANGE = True whileTrue: try: ans = input("| Options: \n|\t[G]et data \n|\t[S]ignatrue \n|\t[F]ault injection \n|\t[Q]uit\n").lower().strip() if ans == 'f': if CHANGE: print(border,"You have one chance to change one byte of N. ") temp,index = input("bytes, and index:").strip().split(",") assert0<= int(temp) <=255 assert0<= int(index) <= 1023 n_ = n ^ (int(temp)<<int(index)) print(border,f"[+] update: n_ -> \"{n_}\"") CHANGE = False else: print(border,"Greedy...") elif ans == 'g': print(border,f"n = {n}") print(border,f"flag_ciphertext = {encrypt(flag,d).hex()}") elif ans == 's': index = input("Where your want to interfere:").strip() sig_ = myfastexp(msg,d,n,int(index),n_) print(border,f"signature of \"Welcome_come_to_WMCTF\" is {sig_}") elif ans == 'q': quit() except Exception as e: print(border,"Err...") quit()