分析: e=3 较小,若 key 较小的话应该直接开方就行,但是尝试了之后不可行,毕竟不会这么直接,也就是说 $key^3>N$,key应该是一个较大的数,爆破了很长时间也打不出来,尝试转换思路。 后来经过多次尝试发现 N 和 c 是不互素的,直接求解最大公因数就能求出 p,q,之后就能求解出 flag 了。 exp.py:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
from Crypto.Util.number import * from Crypto.Util.Padding import pad from Crypto.Cipher import AES import gmpy2 N = 18795243691459931102679430418438577487182868999316355192329142792373332586982081116157618183340526639820832594356060100434223256500692328397325525717520080923556460823312550686675855168462443732972471029248411895298194999914208659844399140111591879226279321744653193556611846787451047972910648795242491084639500678558330667893360111323258122486680221135246164012614985963764584815966847653119900209852482555918436454431153882157632072409074334094233788430465032930223125694295658614266389920401471772802803071627375280742728932143483927710162457745102593163282789292008750587642545379046283071314559771249725541879213 c = 10533300439600777643268954021939765793377776034841545127500272060105769355397400380934565940944293911825384343828681859639313880125620499839918040578655561456321389174383085564588456624238888480505180939435564595727140532113029361282409382333574306251485795629774577583957179093609859781367901165327940565735323086825447814974110726030148323680609961403138324646232852291416574755593047121480956947869087939071823527722768175903469966103381291413103667682997447846635505884329254225027757330301667560501132286709888787328511645949099996122044170859558132933579900575094757359623257652088436229324185557055090878651740 iv = b'\x91\x16\x04\xb9\xf0RJ\xdd\xf7}\x8cW\xe7n\x81\x8d' ciphertext = 0xbf87027bc63e69d3096365703a6d47b559e0364b1605092b6473ecde6babeff2 e = 3 p = gmpy2.gcd(N,c) q = N // p phi = (p-1)*(q-1) d = gmpy2.invert(e,phi) key1 = pow(c,d,N) print(key1) plaintext = AES.new(key = long_to_bytes(key1)[:16], iv = iv, mode = AES.MODE_CBC).decrypt(long_to_bytes(ciphertext)) print(plaintext)
defconstruct_a_row(RNG): row = [] for i inrange(NUM_ITERATIONS): RNG.getrandbits(8) r2_val = RNG.getrandbits(16) r2_high_byte = r2_val >> 8 row += list(map(int, (bin(r2_high_byte)[2:].zfill(8)))) #当 i 为 64 的倍数时,取高 15 位 if (i % 64 == 0): r2_low_byte = r2_val & 0xff r2_low_bits_7 = r2_low_byte >> 1 row += list(map(int, (bin(r2_low_bits_7)[2:].zfill(7)))) return row
L = [] for i in trange(MT_STATE_BITS): state = [0] * 624 temp = "0" * i + "1" + "0" * (MT_STATE_BITS - 1 - i) for j inrange(624): state[j] = int(temp[32*j : 32*j+32], 2) RNG.setstate((3, tuple(state + [624]), None)) L.append(construct_a_row(RNG))
L = Matrix(GF(2), L)
R = [] for i inrange(NUM_ITERATIONS): x_high_byte = gift_bytes[2*i] R += list(map(int, (bin(x_high_byte)[2:].zfill(8)))) if (i % 64 == 0): x_low_byte = gift_bytes[2*i+1] x_low_bits_7 = x_low_byte >> 1 R += list(map(int, (bin(x_low_bits_7)[2:].zfill(7))))