題目如下:
在不分解n的前提下,求d。 給定: e = 14058695417015334071588010346586749790539913287499707802938898719199384604316115908373997739604466972535533733290829894940306314501336291780396644520926473 n = 33608051123287760315508423639768587307044110783252538766412788814888567164438282747809126528707329215122915093543085008547092423658991866313471837522758159 說明過程。
這種e很大的,d可能就會比較小,可能會滿足Wiener’s attack的條件,介紹如下:
英文:
這里有兩個概念,連分數和漸進分數,詳情自行谷歌百度
連分數概念圖:
漸進分數概念:
我的理解:
上面的等式應該比較容易理解,就是等式右邊的分母很大,作為整體很小,意味着等式左邊的減數和被減數的差距很小很小,並且可以通過被減數的連分數求解不斷逼近它本身的一個漸進分數,因此可能會存在某個漸進分數可以滿足減數的要求;
當然按照求解的漸進分數的分子分母分別對應減數的分子分母,因此從頭將所有的漸進分數的分子分母求解出來。
在rsa中, φ(n)= pq - (p + q) + 1 = N - (p + q) + 1,N = pq ,其中p和q都是素數,因此可以推出 φ(n)和N之間的表達式。
搬運的代碼如下:

import gmpy2 def transform(x,y): #使用輾轉相處將分數 x/y 轉為連分數的形式 res=[] while y: res.append(x//y) x,y=y,x%y return res def continued_fraction(sub_res): numerator,denominator=1,0 for i in sub_res[::-1]: #從sublist的后面往前循環 denominator,numerator=numerator,i*numerator+denominator return denominator,numerator #得到漸進分數的分母和分子,並返回 #求解每個漸進分數 def sub_fraction(x,y): res=transform(x,y) res=list(map(continued_fraction,(res[0:i] for i in range(1,len(res))))) #將連分數的結果逐一截取以求漸進分數 return res def get_pq(a,b,c): #由p+q和pq的值通過維達定理來求解p和q par=gmpy2.isqrt(b*b-4*a*c) #由上述可得,開根號一定是整數,因為有解 x1,x2=(-b+par)//(2*a),(-b-par)//(2*a) return x1,x2 def wienerAttack(e,n): for (d,k) in sub_fraction(e,n): #用一個for循環來注意試探e/n的連續函數的漸進分數,直到找到一個滿足條件的漸進分數 if k==0: #可能會出現連分數的第一個為0的情況,排除 continue if (e*d-1)%k!=0: #ed=1 (mod φ(n)) 因此如果找到了d的話,(ed-1)會整除φ(n),也就是存在k使得(e*d-1)//k=φ(n) continue phi=(e*d-1)//k #這個結果就是 φ(n) px,qy=get_pq(1,n-phi+1,n) if px*qy==n: p,q=abs(int(px)),abs(int(qy)) #可能會得到兩個負數,負負得正未嘗不會出現 d=gmpy2.invert(e,(p-1)*(q-1)) #求ed=1 (mod φ(n))的結果,也就是e關於 φ(n)的乘法逆元d return d print("該方法不適用") e = 14058695417015334071588010346586749790539913287499707802938898719199384604316115908373997739604466972535533733290829894940306314501336291780396644520926473 n = 33608051123287760315508423639768587307044110783252538766412788814888567164438282747809126528707329215122915093543085008547092423658991866313471837522758159 d=wienerAttack(e,n) print("d=",d)
參考:https://www.tr0y.wang/2017/11/06/CTFRSA/index.html
https://blog.csdn.net/qq_33737036/article/details/78199297
https://en.wikipedia.org/wiki/Wiener%27s_attack