Crypto知識相關——RSA演算法原理與python實現
阿新 • • 發佈:2019-02-13
RSA加密與解密
RSA加密過程
1. 隨機選擇兩個不相等的質數 p 和 q
e.g 選擇兩個不想等的質數 p 和 q
# python 實現
import gmpy2
import random
p=gmpy2.mpz(random.randint(1,100000)) #初始化
q=gmpy2.mpz(random.randint(1,100000)) #初始化
gmpy2.is_prime(p) #概率性素性測試
gmpy2.is_prime(q) #概率性素性測試
2. 計算n=p*q
如程式碼所示,len就是祕鑰的長度
n=p*q
len=len(bin(n))-2 #python進位制轉換的時候會把0b 加上去
3. 計算n的尤拉函式
Euler_n=(p-1)(q-1)
4. 選擇一個整數 e ,e大於1小於oula_n,並且e和oula_n互質
e=65537 #通常e 選擇 65537
#while(1):
e=random.ranint(1,oula_n)
if (互質):
break
5. 計算e對於oula_n的模反元素d
模反元素可以用擴充套件歐幾里得演算法求解
其中 a=e b=Euler_n
def ext_euclid ( a , b ):
if (b == 0 ):
return 1, 0, a
else:
x , y , q = ext_euclid( b , a % b )
x , y = y, ( x - (a // b) * y )
return x, y, q
計算過程完畢
6. 將n,e封裝為公鑰,n,d封裝為私鑰
公鑰(n,e);私鑰(n,d)
實際應用中,公鑰和私鑰的資料都採用ASN.1格式表達。
如果相對asn.1有著更深的認識,點選這裡
7. 利用公鑰加密
對於資訊m(字串取ascii或者unicode,應該是2進位制或者10進位制?)
利用之前生成的公鑰(n,e)加密。其中m必須小於n
#m**e == c % n
#求出其中的C,就是密文
#其中key是(n,e)
def encrypt(m, key):
C, x = key
return (m ** x) % C
#提供簡單的方法
pow(m,e,(q*p))
8. 用私鑰解密
密文C後,用私鑰(n,d)解密,通過下列式子
#c**d == m % n
#其中key是(n,d)
#將key回到到encrypt(m,key)就可以得出
#提供簡單的方法
pow(c,d,(p*q))
於是你就可以的到 m了。
9. 如果m>n?
如果要加密大於n的整數,該怎麼辦?有兩種解決方法:一種是把長資訊分割成若干段短訊息,每段分別加密;另一種是先選擇一種”對稱性加密演算法”(比如DES),用這種演算法的金鑰加密資訊,再用RSA公鑰加密DES金鑰。
10. 證明可靠性
去看原文部落格吧,這裡就不寫了。
RSA 逆向
RSA中,一共出現了 p,q,n,Euler_n,e,d
六個數字。其中,n,e是公開的公鑰,而其他四個不公開。
已知n,e推d
(1)ed≡1 (mod φ(n))。只有知道e和φ(n),才能算出d。
(2)φ(n)=(p-1)(q-1)。只有知道p和q,才能算出φ(n)。
(3)n=pq。只有將n因數分解,才能算出p和q。
然而,兩個質數的成績是非常難確定的,這也造成了RSA逆向之困難
RSA python實現
當然,如果我們知道 p q n 的話就簡單很多了。
python RSA 簡單實現
當然,如果做CTF題目的話,我覺得這個程式碼可以借鑑一下。PYTHON實現RSA的簡潔程式碼
自己動手寫 rsa 加密和解密
if __name__ == '__main__':
p = gmpy2.mpz( ) # 初始化
print gmpy2.is_prime(p) # 概率性素性測試
q = gmpy2.mpz( ) # 初始化
print gmpy2.is_prime(p) # 概率性素性測試
c = gmpy2.mpz( ) #c 是加密的字串
Euler_n = gmpy2.mpz(10000)
e = gmpy2.mpz(65537) #一般都這麼長
Euler_n = (p - 1) * (q - 1)
d = gmpy2.invert(e, Euler_n)
print "private key:"
print d #獲取私鑰
string = str(pow(c, d, p * q)) #解密字串
# pow(x,y,z)=x**y%z 今天才發現pow原來有三個引數。。。我在感覺專門是給rsa加密解密的?
f = open("flag.txt", "w")
f.write(string)
f.close()
print pow(pow(c, d, p * q),e,(q*p))
#檢查一下,沒毛病