RSA攻擊總結


RSA攻擊基本原理及代碼實現總結

1. n分解攻擊

1. 原理

1. 基本字符含義

m:明文

c:密文

d:私鑰

n:模數

phi:n的歐拉函數值

e:加密鑰

yin:n分解得到的所有因數

2. 攻擊原理描述

已知常規RSA算法原理可由以下五個式子表達

\[m^e \equiv c(mod ~~ n)\tag{1} \]

\[c^d \equiv m(mod ~~ n)\tag{2} \]

\[n = p \times q\tag{3} \]

\[φ(n) = (p-1) \times (q-1)\tag{4} \]

\[e \times d \equiv (mod ~~ φ(n))\tag{5} \]

而非常規RSA算法原理與常規RSA算法原理僅(4)(5)式不同

(4)式改為

\[n = p^{p'} \times q^{q'} \times r^{r'} \times s^{s'} \times ···\tag{6} \]

而(5)式改為

\[φ(n) = p^{p'-1} \times (p-1) \times q^{q'-1} \times (q-1) \times r^{r'-1} \times (r-1) \times s^{s'-1} \times (s-1) \times ···\tag{7} \]

由上述式子可得到當n可以被分解時,很容易得到p,q,r,s,p',q',r',s'的值

可以通過(4)計算得到φ(n)

進而求e在模φ(n)條件下的模逆d

即可獲取明文

那么如合通過實際可行的辦法分解n

  1. 通過python庫文件factordb進行分解(實際上依托於factordb.com的網站存儲已知因數的分解)
  2. 通過yafu小型軟件進行分解(針對p,q之間差距過大或過小的n值)

3. 適用條件

  1. 當n可以通過上述兩種方式分解時

2.代碼

1. 實現

from Crypto.Util.number import long_to_bytes
from factordb.factordb import FactorDB
from functools import reduce
from gmpy2 import invert
from re import findall
from os import popen

#用於RSA的n分解攻擊
#程序會通過上述兩種方式分解因式
def RSA_attack_easy(n,e=-1,c=-1,yin=[]):
    with open('data.txt','wb+') as f:
        f.write(f'n={n}'.encode())
    if yin == []:
        f = FactorDB(n)
        try :
            f.connect()
            sign = f.get_status()
            if sign == 'FF':
                yin = sorted(list(set(f.get_factor_list())))
            elif sign == 'CF':
                yin = list(f.get_factor_list())
                for i in yin:
                    n //= i
                with open('data.txt','wb+') as f:
                        f.write(f'{n}\n'.encode())
                result = popen(r'D:\學習相關\密碼學相關\密碼學工具\yafu-1.34\yafu-x64 "factor(@)" -batchfile data.txt','r')
                str_yin = findall(r'P\d+ = (\d)+\n',result.read())
                for x in str_yin:
                    yin.append(int(x))
                yin = sorted(list(set(yin)))
            else :
                with open('data.txt','wb+') as f:
                        f.write(f'{n}\n'.encode())
                result = popen(r'D:\學習相關\密碼學相關\密碼學工具\yafu-1.34\yafu-x64 "factor(@)" -batchfile data.txt','r')
                str_yin = findall(r'P\d+ = (\d)+\n',result.read())
                yin = [int(x) for x in str_yin]
                if yin == []:
                    return 'n不可分解'
        except:
            return 'n不可分解'
    yu = n//reduce(lambda x, y: x*y, yin)
    phi = 1
    for i in yin:
        phi *= (i-1)
    phi *= yu
    if e != -1:
        e %= phi
        d = invert(e,phi)
        if c!=-1:
            ci = long_to_bytes(pow(c,d,n))
            return(ci,c,f'd:{d}')
        else :
            return f'd:{d}'
    else :
        return(f'因數有:{yin}',f'歐拉系數:{phi}')

2. 代碼說明

1. 返回說明
  1. 當函數僅輸入參數n時,函數返回n的所有因數和phi
  2. 當函數僅輸入參數n,e時,函數返回d
  3. 當函數僅輸入參數n,e,c時,返回明文m的字符值和數值並返回d
  4. 當函數僅輸入參數n,e,c,yin時,返回明文m的字符值和數值並返回d
  5. 無論輸入參數是什么,當n不能通過上述兩種方式分解時,返回‘n不可分解’
2. 輸入說明
  1. n,e,c均為整數
  2. yin為整數列表

2. 共模攻擊

1. 原理

1. 基本字符含義

m:明文

c:密文

d:私鑰

n:模數

phi:n的歐拉函數值

e:加密鑰整數集合或列表

yin:n分解得到的所有因數的集合或列表

\(e_1\):加密鑰舉例1

\(c_1\):用加密鑰舉例1加密m得到的密文

\(e_2\):加密鑰舉例2

\(c_2\):用加密鑰舉例1加密m得到的密文

2. 攻擊原理描述

假設e1,e2互質,即:

\[gcd(e_1,e_2)=1\tag{1} \]

即存在:

\[e_1*s_1+e_2*s_2~ = ~1 \tag{2} \]

\[\because c_1 = m^{e_1}(\mod n),c_2 = m^{e_2}(\mod n)\tag{3} \]

\[\therefore c_1^{s_1} \times c_2^{s_2} \equiv (m^{e_1})^{s_1} \times (m^{e_2})^{s_2}(\mod n)\tag{4} \]

由(2)式與(4)式得:

\[c_1^{s_1} \times c_2^{s_2} \equiv m^1 (\mod n) \tag{5} \]

由此可得,當求出\(s_1\)\(s_2\)時,即可解得獲得明文

如何求\(s_1\)\(s_2\)

答案是:擴展歐幾里得算法

3. 適用條件

  1. 當同份明文被互質的加密指數加密時

2. 代碼

1. 實現

from Crypto.Util.number import long_to_bytes,bytes_to_long
from gmpy2 import invert
from egcd import egcd
#RSA共模攻擊
def RSA_mo(n,e1,c1,e2,c2):
    '''#RSA共模攻擊'''
    s,s1,s2 = egcd(e1,e2)
    if s1<0:
        s1,s2 = s2,s1
        e1,e2 = e2,e1
        c1,c2 = c2,c1
    if s!=1:
        return '不能進行互素的共模攻擊'
    c2 = invert(c2,n)
    m = (pow(c1,s1,n)*pow(c2,-s2,n))%n
    return m,long_to_bytes(m)

2. 代碼說明

1. 輸入說明
  1. 參數n,e1,e2,c1,c2都要輸入
  2. e1代表\(e_1\)參數以此類推
2. 輸出說明

返回m的數值與字符值

3. 低解密指數攻擊(維納攻擊)

1. 原理

1. 基本字符含義

m:明文

c:密文

n:模數

d:私鑰

phi:n的歐拉函數值

e:加密鑰

2. 攻擊原理描述

理論基礎(勒讓德定理):當e過大或過小時,\(\dfrac e n\)連分數展開會逐漸趨向於\(\dfrac k d\)

原文:Let $\alpha \in \mathbb{Q} $ and \(c,d \in \mathbb{Z}\) satisfy

\[|\alpha - \dfrac{c}{d}| < \dfrac{1}{2d^2} \]

Then c/d, in lowest terms, is one of the convergents in the continued fraction expansion of \(\alpha\).

\[phi = (p-1) \times (q-1) = p \times q - p - q +1\tag{1} = n - (p +q )+1 \]

\[\because p \times q >> p+q \tag{2} \]

\[\therefore phi \approx n \tag{3} \]

\[e \times d \equiv 1 (\mod phi) \]

\[e \times d - 1 = k \times d \tag{4} \]

由(2)兩邊同時除\(d \times phi\)可得:

\[\dfrac{e}{phi} - \dfrac k d =\dfrac 1 { d \times phi} \tag{5} \]

\[\because\dfrac 1 {d \times phi} \approx 0 \tag{6} \]

\[\therefore \frac{e}{phi} \approx \dfrac k d \tag{7} \]

\[(p+q) = n-phi +1 \approx n - \dfrac{ed}{k} + 1 \tag{8} \]

雖然在此式子中無法得知d和k的具體值,但是由於連分數逼近原理可以得到兩者之間的比值所以(p+q)是可以得到相對接近的值的

再通過構造方程

\[x^2 - (p+q)x +p \times q = 0\tag{10} \]

韋達定理: \(x_1 + x_2 = (p+q) , ~~ x_1 \times x_2 = n\)

求解方程即可得到p,q的值

3. 適用條件

  1. 當e極大或極小時

2. 代碼

1. 實現

c = continued_fraction(e/n) #直接輸出e/n的連分數展開的數組
alist = c.convergents() #求e/n的連分數逼近
from Crypto.Util.number import long_to_bytes
from gmpy2 import invert,isqrt
from libnum import n2s,s2n
#低解密指數攻擊
#條件:d<pow(n,0.25)/3
def RSA_wiener (n,e,c):
    #連分數逼近,並列出逼近過程中的分子與分母
    def lian_fen(x,y):
        res = []
        while y:
            res.append(x//y)
            x,y = y,x%y
        resu = []
        for j in range(len(res)):
            a,b = 1,0
            for i in res[j::-1]:
                b,a = a,a*i+b
            resu.append((a,b))
        if resu[0] == (0,1):
            resu.remove((0,1))
        return resu[:-1]
    lianfen = lian_fen(e,n)
    def get_pq(a,b,c):
        par = isqrt((n-phi+1)**2-4*n)
        x1,x2 = (-b + par) // (2 * a), (-b - par) // (2 * a)
        return x1,x2
    for (k,d) in lianfen:
        phi = (e*d-1)//k
        p,q = get_pq(1,n-phi+1,n)
        if p*q == n:
            p,q = abs(int(p)),abs(int(q))
            d = invert(e,(p-1)*(q-1))
            break
    return m,long_to_bytes(pow(c,d,n))

2. 代碼說明

1. 輸出說明

返回m的數值與字符值

4. dp泄露攻擊

1. 原理

1. 基本字符含義

m:明文

c:密文

n:模數

d:私鑰

phi:n的歐拉函數值

dp:d對(p-1)取模

2. 攻擊原理描述

當dp泄露時,n可分解成的素數種類大大降低,變得“可預測”

\[dp \equiv d \mod (p-1) \tag{1} \]

\(⇒dp \times e \equiv d \times e \mod(p-1)\)

\(⇒d \times e = k \times (p-1) +dp \times e\)

\(d \times e \equiv 1 \mod(p-1) \times(q-1)\)

\(⇒k\times(p-1) + dp \times e \equiv 1 \mod (p-1)\times(q-1)\)

\(⇒k \times (p-1) +dp \times e = k_1 \times (p-1) \times (q-1) + 1\)

\(⇒dp \times e = (k_1\times q + k_1 - k) \times (p-1) + 1\)

設:$X = (k_1\times q + k_1 - k) $

$⇒dp \times e = X \times (p-1) +1 $

\(dp < (p-1)\)

\(⇒e>X\)

\(X \in [0,e]\)

遍歷[0,e]即可找出X,進而通過上述公式求得p,從而達到n分解的目的

2. 代碼

1. 實現

from Crypto.Util.number import long_to_bytes
from gmpy2 import invert
from factordb.factordb import FactorDB
#dp泄露攻擊
def RSA_dp_reveal(dp,e,n,c):
    for X in range(2,e):
        if (dp*e-1)%X==0:
            p = (dp*e-1)//X + 1
            if n%p == 0:
                q = n // p
                break
    phi = (p-1)*(q-1)
    d = invert(e,phi)
    ci = long_to_bytes(pow(c,d,n))
    return ci

2. 代碼說明

1. 輸出說明

返回m的數值與字符值

5. dp,dq泄露

1. 原理

1. 基本字符含義

m:明文

c:密文

n:模數

d:私鑰

phi:n的歐拉函數值

dp:d對(p-1)取模

dq:d對(q-1)取模

2. 條件

dp,dq,c,p,q且dp與dq互素,且\(p<q\)

3. 攻擊原理描述

n未知,首先計算\(n = p \times q\)

又已知:

\[d = dp \mod (p-1) \]

\[d = dq \mod (q-1) \tag{1} \]

又設得\(m_1,m_2\)

\[c^d \equiv m_1 (\mod p)(m_1為特定數值,使該式成立) \]

\[c^d \equiv m_2 (\mod q)(m_2為特定數值,使該式成立)\tag{2} \]

又可得:

\[c^d = m_1 + kp (k為特定數值,使該式成立) \]

\[m_2 \equiv (kp + m_1)(\mod q) \]

\[(m_2-m_1)\equiv kp (\mod q) \tag{3} \]

因為\(gcd(p,q)=1\)\(p<q\)所以:

\[在模q的條件下,存在p^{-1} \]

\[ k \equiv (m_2-m_1)p^{-1} \mod q \tag{4} \]

還要注意得一個問題是p<q,如果不成立,則一定不存在\(p^{-1}\)

\(c^d = m_1 + kp,k \equiv (m_2-m_1)p^{-1} \mod q\)可得:

\[c^d = ((m_2 -m_1)\times p^{-1}\mod q)\times p+m_1\tag{5} \]

\(m\equiv c^d \mod n\)得:

\[m \equiv ((m_2 -m_1)\times p^{-1}\mod q)\times p+m_1 \mod n\tag{6} \]

\[d = dp + k_1\times(p-1)(k_1為特定數值,使該式成立) \]

\[m_1 \equiv c^{d} \mod p \]

\[m_1 \equiv c^{dp + k_1 \times(p-1)} \mod p \tag{7} \]

由費馬小定理\(c^{p-1} \equiv 1 (\mod p)\)可得:

\[m_1 \equiv c^{dp} \mod p \tag{8} \]

同理得:

\[m_2 \equiv c^{dq} \mod q \tag{9} \]

最后由(5)、(8)、(9)可計算得m

2. 代碼

1. 實現

from gmpy2 import invert
from libnum import n2s

def dp_dq_RSA_attack(dp,dq,p,q,c):
    if p>q:
        p,q = q,p
        dp,dq = dq,dp
    n = p*q
    m1 = pow(c,dp,p)
    m2 = pow(c,dq,q)
    inv_p = invert(p,q)
    m = ((m2-m1)*inv_p%q*p+m1)%n
    return int(m),n2s(int(m))

2. 代碼說明

1. 輸入說明

需要輸入dp,dq,p,q,c

2. 輸出說明

返回m的數值與字符值

6. 低加密指數攻擊

1. 原理

1. 基本字符含義

m:明文

c:密文

n:模數

2. 條件

  1. 當加密指數e非常小時

3. 攻擊原理描述

已知:

\[m^e \equiv c (\mod n) \]

\[m^e = k \times n + c(k為特定數值,使該式成立)\tag{1} \]

當加密指數e非常小時,k也會非常小,通過暴力的方式,即可獲得m,從而獲得e

2. 代碼

1. 實現

from gmpy2 import iroot
from libnum import n2s

def little_e_RSA_attack(e,n,c):
    for k in range(1000000000):
        if iroot(c+k*n,e)[1] == True:
            return (n2s(int(iroot(c+k*n,e)[0])))

7. 低加密指數廣播攻擊

1. 原理

1. 基本字符含義

\(n_1,n_2,···,n_n\):不同的加密所使用的模數

\(c_1,c_2,···,c_n\):不同加密所獲得的密文

2. 原理

已知:

\[m^e \equiv c_1(\mod n_1) \]

\[m^e \equiv c_2(\mod n_2) \]

\[··· \]

\[m^e \equiv c_n(\mod n_n) \]

根據中國剩余定理可求得\(m^e\)

可能題目中會存在模不互素,這時候就要用到模不互素的中國剩余定理

然后通過爆破的方式獲取e

2. 代碼

1. 實現

import re
from gmpy2 import gcd,invert
from libnum import n2s
def low_exponent_attack(e,text_n,text_c):
    n_text = re.findall(r"(n\d)\s*=\s*(\d+)\s*\n",text_n)
    c_text = re.findall(r"(c\d)\s*=\s*(\d+)\s*\n",text_c)
    n_map = {a:int(b) for a,b in n_text}
    c_map = {a:int(b) for a,b in c_text}
    for i in n_map:
        for j in n_map:
            if i!=j:
                p = gcd(n_map[i],n_map[j])
                q = n_map[i]//p
                d = invert(e,(p-1)*(q-1))
                m = pow(c_map["c"+i[1:]],d,n_map[i])
                return n2s(m)

2.代碼說明

1. 輸入說明

輸入為 "n\d = \d+"正則形式的文本,由程序自動識別並錄入

2. 輸出說明

程序自動輸出解密的明文

8. e和phi不互素

1. 原理

1. 基本字符含義

字符 含義
phi,\(\phi(n)\) n的歐拉函數
e 加密指數
p,q n的兩個因數

2. 原理

尋找一個b使其滿足如下條件

\[e \equiv 0 (\mod b) \]

\[gcd(\dfrac e b,\phi(n)) = 1 \]

相當於變成了一個新的RSA解密

\[(m^b)^{\frac eb} \equiv c (\mod n) \tag 1 \]

按照正常的RSA解密流程

\[d_b = (\frac eb)^{-1}(\mod \phi(n)) \tag 2 \]

\[m^b \equiv c^{d_b} (\mod n) \tag 3 \]

然后嘗試對\(m^b\)進行開根算法(對n肯定是開不了根的)

\[m^b \equiv c_1 (\mod p) \]

\[m^b \equiv c_2 (\mod q) \tag 4 \]

第一個方程可以解出b個m,第二個方程也可以解出b個m。

已知兩個方程的解中肯定有為真正的解模p和模q的結果記為\(m_1,m_2\)

使用中國剩余定理解同余方程,共\(b^2\)個組合,可以獲得\(B^2\)個m的值

\[m \equiv m_1 (\mod p ) \]

\[m \equiv m_2 (\mod q) \tag 5 \]

篩選一下即可獲得m的值

2. 代碼

1. 實現

# sagemath
from libnum import n2s
def e_phi_not_coprime(p,q,e,c,hint:str):
    n = p*q
    phi = (p-1)*(q-1)
    b = gcd(phi,e)
    e_b = e//b
    while gcd(phi,e_b)!=1:
        b *= gcd(phi,e_b)
        e_b //= gcd(phi,e_b)
    d_b = inverse_mod(e_b,phi)
    m_b = pow(c,d_b,n)
    P.<m1> = PolynomialRing(Zmod(p))
    P.<m2> = PolynomialRing(Zmod(q))
    f1 = m1^(e//e_b) - m_b%p
    f2 = m2^(e//e_b) - m_b%q
    roots1 = {x[0] for x in f1.monic().roots()}
    roots2 = {x[0] for x in f2.monic().roots()}
    for m1 in roots1:
        for m2 in roots2:
            m = crt([int(m1),int(m2)],[int(p),int(q)])
            if hint.encode() in n2s(int(m)):
                return (n2s(int(m)))

2. 代碼說明

  1. 輸入說明:hint要求為str形式,且是最后flag一定含有的內容用於挑選
  2. 輸出說明:直接輸出合適的形式

9. p-1光滑

1. 原理

生成質數的算法不當會造成易遭受Pollard's p-1 method的分解攻擊。

當p-1是可以分解為多個小質因數時,且已知其中最大的因數B

可知B和p-1滿足以下等式:

\[(p-1)|B! \]

根據費馬定理可知

\[a^{B!} \equiv a^{t\times (p-1)} \equiv 1 (\mod p) \]

可知:

\[gcd((a^{B!}-1),N) = p \]

極易

2. 代碼

# sagemath
from libnum import n2s
# 重寫pow函數加快運算速度
def pow(m,e,n):
    type = m % n
    res = 1
    while e > 0:
        if e&1:
            res = (res * type) % n
        type = (type * type) % n
        e >>= 1
    return res 
def Pollards_method(N,a=2,B):
    p = gcd(pow(a,factorial(B),N)-1,N)
    q = N//p
    phi = (p-1)*(q-1)
    d = inverse_mod(e,phi)
    m = pow(c,d,N)
    return n2s(int(m))


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM