算是基礎題,有不少以前題的影子,作不出來純屬菜。python
from Crypto.Util.number import * class Key: def __init__(self, bits): assert bits >= 512 self.p = getPrime(bits) self.q = getPrime(bits) self.n = self.p * self.q self.e = 0x100007 self.d = inverse(self.e, (self.p-1)*(self.q-1)) self.dmp1 = self.d%(self.p-1) self.dmq1 = self.d%(self.q-1) self.iqmp = inverse(self.q, self.p) self.ipmq = inverse(self.p, self.q) def encrypt(self, data): num = bytes_to_long(data) result = pow(num, self.e, self.n) return long_to_bytes(result) def decrypt(self, data): num = bytes_to_long(data) v1 = pow(num, self.dmp1, self.p) v2 = pow(num, self.dmq1, self.q) result = (v2*self.p*self.ipmq+v1*self.q*self.iqmp) % self.n return long_to_bytes(result) def __str__(self): return "Key([e = {0}, n = {1}, x = {2}, y = {3}])".format(self.e, self.d, self.iqmp, self.ipmq) def main(): key = Key(1024) flag = open('flag').read() encrypt_flag = key.encrypt(flag) assert key.decrypt(encrypt_flag) == flag print key print encrypt_flag.encode('hex') if __name__ == '__main__': main()
Key([e = 1048583, n = 20899585599499852848600179189763086698516108548228367107221738096450499101070075492197700491683249172909869748620431162381087017866603003080844372390109407618883775889949113518883655204495367156356586733638609604914325927159037673858380872827051492954190012228501796895529660404878822550757780926433386946425164501187561418082866346427628551763297010068329425460680225523270632454412376673863754258135691783420342075219153761633410012733450586771838248239221434791288928709490210661095249658730871114233033907339401132548352479119599592161475582267434069666373923164546185334225821332964035123667137917080001159691927, x = 22886390627173202444468626406642274959028635116543626995297684671305848436910064602418012808595951325519844918478912090039470530649857775854959462500919029371215000179065185673136642143061689849338228110909931445119687113803523924040922470616407096745128917352037282612768345609735657018628096338779732460743, y = 138356012157150927033117814862941924437637775040379746970778376921933744927520585574595823734209547857047013402623714044512594300691782086053475259157899010363944831564630625623351267412232071416191142966170634950729938561841853176635423819365023039470901382901261884795304947251115006930995163847675576699331]) 32074de818f2feeb788e36d7d3ee09f0000381584a72b2fba0dcc9a2ebe5fd79cf2d6fd40c4dbfea27d3489704f2c1a30b17a783baa67229d02043c5bc9bdb995ae984d80a96bd79370ea2c356f39f85a12d16983598c1fb772f9183441fea5dfeb5b26455df75de18ce70a6a9e9dbc0a4ca434ba94cf4d1e5347395cf7aafa756c8a5bd6fd166bc30245a4bded28f5baac38d024042a166369f7515e8b0c479a1965b5988b350064648738f6585c0a0d1463bd536d11a105bb926b44236593b5c6c71ef5b132cd9c211e8ad9131aa53ffde88f5b0df18e7c45bcdb6244edcaa8d386196d25297c259fca3be37f0f2015f40cb5423a918c51383390dfd5a8703
題目給定了e,d,x,y,\(x = q^{-1} \mod p,y = p^{-1} \mod q\)(代碼命名混亂)。app
根據rsa的原理,\(ed == 1 \mod \phi(n)\),故\(e*d-1\)必定是\(\phi(n)\)的倍數,即\(e*d-1==k*\phi(n)\),\(k\)是整數,因爲\(d<n\)故\(k<e\)。\(e\)的值不是很大,經過枚舉能夠肯定全部\(k\)的可能值,代入\(e*d-1==k*\phi(n)=k*(p-1)*(q-1)\),獲得關於\(p,q\)的方程。憑藉直覺,經過\(x,y\)確定能肯定另一個方程,最後解出\(p,q\)。dom
\[xq = 1 + w_1*p,yp = 1 + w_2*q\]加密
\[xq-1 = w_1*p,yp-1 = w_2*q\]spa
咱們的目的是獲得\(p,q\)的數量關係,勢必要去掉\(w_1,w_2\)。因此兩邊相乘\(xypq-xq-yp+1=w_1w_2pq\),\(xq+yp-1= (xy-w_1w_2)*pq\)。這裏咱們知道\(x<p,y<q\)。因此\(0<(xy-w_1w_2)*pq<2*pq\)。這樣咱們就知道了其實\(xy-w_1w_2=1\)。這樣咱們又獲得了一個關於\(p,q\)的等式。經過兩個方程聯立,最終能夠解出\(p,q\)的值。code
from Crypto.Util.number import long_to_bytes from tqdm import trange import gmpy2,binascii d = 20899585599499852848600179189763086698516108548228367107221738096450499101070075492197700491683249172909869748620431162381087017866603003080844372390109407618883775889949113518883655204495367156356586733638609604914325927159037673858380872827051492954190012228501796895529660404878822550757780926433386946425164501187561418082866346427628551763297010068329425460680225523270632454412376673863754258135691783420342075219153761633410012733450586771838248239221434791288928709490210661095249658730871114233033907339401132548352479119599592161475582267434069666373923164546185334225821332964035123667137917080001159691927 x = 22886390627173202444468626406642274959028635116543626995297684671305848436910064602418012808595951325519844918478912090039470530649857775854959462500919029371215000179065185673136642143061689849338228110909931445119687113803523924040922470616407096745128917352037282612768345609735657018628096338779732460743 y = 138356012157150927033117814862941924437637775040379746970778376921933744927520585574595823734209547857047013402623714044512594300691782086053475259157899010363944831564630625623351267412232071416191142966170634950729938561841853176635423819365023039470901382901261884795304947251115006930995163847675576699331 e = 1048583 klist = [] for i in trange(1,e): if (e*d-1)%i==0: klist.append(i) print(len(klist)) nlist = [] for k in klist: w = (e*d-1)//k a = y-1 b = x-y-w c = 1-x+w*x delt = b*b-4*a*c if delt<0 : continue s,t = gmpy2.isqrt_rem(delt) if t!=0: continue if (s-b)%(2*a)!=0: continue q = (s-b)//(2*a) if (w+q-1)%(q-1)!=0: continue p = (w+q-1)//(q-1) n = p*q nlist.append(n) print(nlist) n = 22509077260984027608263845908083202879597081619164800783060781115945741547031252889863077300004310236160814653393991988068104999928735140821504649764471313283345921984799288521496479399032837319974588038186917872597078510975400908137738190304700710900604891709265153418588830065918981914371070605822998222527238465925300150253661563857557769597206945843298561291788401379974127990007737364134474570192828364417568030703631487414510799126846577679080152555651843717973023204220528124089432708534457966658829476472791371567790491496967424845002161008643478300481541860754837427906812836584810660110698219790829058527133 c = 0x32074de818f2feeb788e36d7d3ee09f0000381584a72b2fba0dcc9a2ebe5fd79cf2d6fd40c4dbfea27d3489704f2c1a30b17a783baa67229d02043c5bc9bdb995ae984d80a96bd79370ea2c356f39f85a12d16983598c1fb772f9183441fea5dfeb5b26455df75de18ce70a6a9e9dbc0a4ca434ba94cf4d1e5347395cf7aafa756c8a5bd6fd166bc30245a4bded28f5baac38d024042a166369f7515e8b0c479a1965b5988b350064648738f6585c0a0d1463bd536d11a105bb926b44236593b5c6c71ef5b132cd9c211e8ad9131aa53ffde88f5b0df18e7c45bcdb6244edcaa8d386196d25297c259fca3be37f0f2015f40cb5423a918c51383390dfd5a8703 m = gmpy2.powmod(c,d,n) print(long_to_bytes(m))