RSA演算法與Python實現

taiji1985發表於2018-08-08

RSA演算法與Python實現

yangtf

功能

RSA加密是最常見的非對稱加密演算法,基於大數分解難題。 兩個很大的素數相乘很容易,但想根據成績解出因子則很難。

如果數不夠大,還是很容易分解的。

素數

素數是這樣的整數,它除了能表示為它自己和1的乘積以外,不能表示為任何其它兩個整數的乘積。例如,15=3*5,所以15不是素數;又如,12=6*2=4*3,所以12也不是素數。另一方面,13除了等於13*1以外,不能表示為其它任何兩個整數的乘積,所以13是一個素數。素數也稱為“質數”。

互質數(或互素數)

公約數只有1的兩個數,叫做互質數

模指數運算

取模就是 做一個整除,取餘數作為結果,如 13 % 3 = 1 ,因為13除以3,餘1
模指數運算就是先做指數運算,取其結果再做模運算。

RSA演算法

(1)先隨機選擇兩個足夠大的素數

(2)計算乘積 n = pq ,這個n就是那個很難分解的大數,如果pq太小就尷尬了,很容易被爆破。

(3)計算f(n) = (p-1)*(q-1) ,p和q 不能讓任何人知道。n是公開的。

(4)找到一個與f(n)互質的數e,使其1

import math
p=9648423029010515676590551740010426534945737639235739800643989352039852507298491399561035009163427050370107570733633350911691280297777160200625281665378483
q=11874843837980297032092405848653656852760910154543380907650040190704283358909208578251063047732443992230647903887510065547947313543299303261986053486569407
e=65537
c=83208298995174604174773590298203639360540024871256126892889661345742403314929861939100492666605647316646576486526217457006376842280869728581726746401583705899941768214138742259689334840735633553053887641847651173776251820293087212885670180367406807406765923638973161375817392737747832762751690104423869019034
n=p*q



fn=long((p-1)*(q-1))

# 計算d,使得 de≡1 mod f(n)    
# 意思是  d*e % fn == 1 。 d和e的乘積取模等於1 
# 也就是說 d*e = 1 + fn*i  (i為整數,就是 d*e / fn 的商)
# 下面的演算法是  ( fn*i+i ) % e  如果結果為零,得到結果就是d  

i = 1
while(True):
    x=(i*fn)+1
    if(x%e==0):
        d=x/e
        break
    i=i+1

print "d=", d
print "i=",i

# 另外一個等價公式是  d ≡e-1 mod f(n)   , 意思為 d % f(n) == (e-1)%f(n) , 也就是說 (e-1)+ j*fn = d + f(n)*i 
# 這個比較難算了。
d= 56632047571190660567520341028861194862411428416862507034762587229995138605649836960220619903456392752115943299335385163216233744624623848874235303309636393446736347238627793022725260986466957974753004129210680401432377444984195145009801967391196615524488853620232925992387563270746297909112117451398527453977
i= 32394
KU = (e,n) # 公鑰
PU = (d,n) # 私鑰
M = 5577446633554466577768879988 # 明文
C = pow(M,e,n ) # M的e次方 模上n
print "C = " , C
C =  83208298995174604174773590298203639360540024871256126892889661345742403314929861939100492666605647316646576486526217457006376842280869728581726746401583705899941768214138742259689334840735633553053887641847651173776251820293087212885670180367406807406765923638973161375817392737747832762751690104423869019034
MC = pow(C,d,n)
print "MC = ",MC
MC =  5577446633554466577768879988
M == MC
True

可以看到解密後的MC和原文M相等

Cite :

https://www.cnblogs.com/jiftle/p/7903762.html

http://www.shiyanbar.com/ctf/1979

https://blog.csdn.net/sinat_33769106/article/details/79999090

還有另外一個計算D的方法,試一下。

def computeD(fn, e):
    (x, y, r) = extendedGCD(fn, e)
    if y < 0:
        return fn + y
    return y

def extendedGCD(a, b):
    if b == 0:
        return (1, 0, a)
    x1 = 1
    y1 = 0
    x2 = 0
    y2 = 1
    while b != 0:
        q = a / b
        r = a % b
        a = b
        b = r
        x = x1 - q*x2
        x1 = x2
        x2 = x
        y = y1 - q*y2
        y1 = y2
        y2 = y
    return(x1, y1, a)

D = computeD(fn,e)
print D
56632047571190660567520341028861194862411428416862507034762587229995138605649836960220619903456392752115943299335385163216233744624623848874235303309636393446736347238627793022725260986466957974753004129210680401432377444984195145009801967391196615524488853620232925992387563270746297909112117451398527453977
D == d
True

簡單的證明

C=Me%n

C = M^e \% n

M=Cd%n=Med%n=M1%n=M
M = C^d \% n = M^{ed} \% n = M^{1} \% n = M

為什麼ed = 1 ,在整個公式裡,都是做的模運算 ,生成過程決定了 ed % n = 1
上述公式用latex表述。

相關文章