RSA演算法原理
1976年,兩位美國計算機學家 W h i t f i e l d D i f f i e Whitfield Diffie WhitfieldDiffie 和 M a r t i n H e l l m a n Martin Hellman MartinHellman,提出了一種嶄新構思,可以在不直接傳遞金鑰的情況下,完成解密。這被稱為"Diffie-Hellman金鑰交換演算法"。這個演算法的產生,預示著非對稱加密誕生了。
非對稱加密的場景是:A給B傳送資訊。
- B要先生成兩把金鑰(公鑰和私鑰)。公鑰是公開的,任何人都可以獲得,私鑰則是保密的。
- A獲取B的公鑰,然後用它對資訊加密。
- B得到加密後的資訊,用私鑰解密。
1977年,三位數學家 R i v e s t Rivest Rivest、 S h a m i r Shamir Shamir 和 A d l e m a n Adleman Adleman 設計了一種演算法,可以實現非對稱加密。這種演算法用他們三個人的名字命名,叫RSA演算法。從那時直到現在,RSA演算法一直是最廣為使用的"非對稱加密演算法"。毫不誇張地說,只要有計算機網路的地方,就有RSA演算法。這種演算法非常可靠,金鑰越長,它就越難破解。根據已經披露的文獻,目前被破解的最長RSA金鑰是232個十進位制位,也就是768個二進位制位,因此可以認為,1024位的RSA金鑰基本安全,2048位的金鑰極其安全,當然量子計算機除外。
RSA基本原理
首先我們需要明白幾個基本概念
- 素數:又稱質數,指在一個大於1的自然數中,除了1和此整數本身外,不能被其他自然數整除的數。
- 互質,又稱互素。若N個整數的最大公因子是1,則稱這N個整數互質。
- 模運算即求餘運算。”模“是“ m o d mod mod”的音譯。和模運算緊密相關的一個概念是“同餘”。數學上,當兩個整數除以同一個正整數,若得相同餘數,則二整數同餘。
尤拉函式
任意給定正整數n,請問在小於等於n的正整數之中,有多少個與n構成互質關係?(比如,在1到8之中,有多少個數與8構成互質關係?)計算這個值的方法就叫做尤拉函式,以 ϕ ( n ) \phi (n) ϕ(n)表示。
比如,計算8的尤拉函式,和8互質的 1、2、3、4、5、6、7、8,所以 ϕ ( 8 ) = 4 \phi(8) = 4 ϕ(8)=4
尤拉函式的幾個特性
-
如果n是質數的某一個次方,即 n = p k n = p^k n=pk (p為質數,k為大於等於1的整數),則 ϕ ( n ) = ϕ ( p k ) = p k − p ( k − 1 ) \phi(n)=\phi(p^k)=p^k-p^(k-1) ϕ(n)=ϕ(pk)=pk−p(k−1)。
比如: ϕ ( 8 ) = ϕ ( 2 3 ) = 2 3 − 2 2 = 8 − 4 = 4 \phi(8)=\phi(2^3)=2^3-2^2=8-4=4 ϕ(8)=ϕ(23)=23−22=8−4=4
-
如果n是質數,則 ϕ ( n ) = n − 1 \phi(n)=n-1 ϕ(n)=n−1 。因為質數與小於它的每一個數,都構成互質關係。
比如:計算7的尤拉函式,7是質數, ϕ ( 7 ) = 6 \phi(7) = 6 ϕ(7)=6
-
如果n可以分解成兩個互質的整數之積,即$ n = p * k$ ,則 ϕ ( n ) = ϕ ( p ∗ k ) = ϕ ( p 1 ) ∗ ϕ ( p 2 ) \phi(n) = \phi(p * k) = \phi(p1)*\phi(p2) ϕ(n)=ϕ(p∗k)=ϕ(p1)∗ϕ(p2),
比如: ϕ ( 56 ) = ϕ ( 8 ) ∗ ϕ ( 7 ) = 4 ∗ 6 = 24 \phi(56) = \phi(8) * \phi(7) = 4 * 6 = 24 ϕ(56)=ϕ(8)∗ϕ(7)=4∗6=24
尤拉定理
如果兩個正整數m和n互質,那麼m的
ϕ
(
n
)
\phi(n)
ϕ(n)次方減去1,可以被n整除。
m
Φ
(
n
)
m
o
d
n
≡
1
m^{\Phi (n)} \mod n \equiv 1
mΦ(n)modn≡1
小費馬定理
尤拉定理的特殊情況,如果兩個正整數m和n互質,而且n為質數!那麼φ(n)結果就是n-1
m
(
n
−
1
)
m
o
d
n
≡
1
m^{(n-1)} \mod n \equiv 1
m(n−1)modn≡1
模反元素
如果兩個正整數e和x互質,那麼一定可以找到整數d,使得$ed-1
被
x
整
除
,
或
者
說
被x整除,或者說
被x整除,或者說ed$被x除的餘數是1。那麼d就是e相對於x的模反元素。
e
∗
d
m
o
d
x
≡
1
e*d \mod x \equiv 1
e∗dmodx≡1
以上基本原理都很淺顯,接下來稍微轉化一下
m
Φ
(
n
)
m
o
d
n
≡
1
(1)
m^{\Phi (n)} \mod n \equiv 1 \tag{1}
mΦ(n)modn≡1(1)
m k ∗ Φ ( n ) m o d n ≡ 1 (2) m^{k*\Phi (n)}\mod n \equiv 1 \tag{2} mk∗Φ(n)modn≡1(2)
m k ∗ Φ ( n ) + 1 m o d n ≡ m (3) m^{k*\Phi (n)+1}\mod n \equiv m \tag{3} mk∗Φ(n)+1modn≡m(3)
e ∗ d ≡ k ∗ x + 1 (4) e*d \equiv k*x+1 \tag{4} e∗d≡k∗x+1(4)
m e ∗ d m o d n ≡ m (5) m^{e*d} \mod n \equiv m \tag{5} me∗dmodn≡m(5)
公式3與公式4轉化為公式5,需要一個前提: e e e與 ϕ ( n ) \phi (n) ϕ(n)互質
我們可以將公式5變換一下:
m
e
∗
d
m
o
d
n
=
=
>
(
m
e
)
d
m
o
d
n
(6)
m^{e*d} \mod n ==> (m^e)^d \mod n \tag{6}
me∗dmodn==>(me)dmodn(6)
m e m o d n ≡ c c d m o d n ≡ m m^e \mod n \equiv c \\ c^d \mod n \equiv m memodn≡ccdmodn≡m
第一個用於加密,第二個用於解密。假設 m = 12 m=12 m=12(隨便取值,只要比n小就可以), n = 15 n=15 n=15(還是隨機取一個值,不一定非要互質), ϕ ( n ) = 8 \phi(n) = 8 ϕ(n)=8, e = 3 e=3 e=3( e e e必須和 ϕ ( n ) \phi(n) ϕ(n)互質),這裡取 d = 19 d=19 d=19( 3 d − 1 = 8 3d-1=8 3d−1=8,d也可以為3,11等等,也就是 d = ( 8 k + 1 ) / 3 d = (8k + 1) / 3 d=(8k+1)/3)
演算法過程
- 隨意選擇兩個大的質數p和q,p不等於q,計算 N = p ∗ q N=p*q N=p∗q。
- 根據尤拉函式,不大於N且與N互質的整數的個數為 ( p − 1 ) ( q − 1 ) (p-1)(q-1) (p−1)(q−1)。
- 選擇一個整數e與 ( p − 1 ) ( q − 1 ) (p-1)(q-1) (p−1)(q−1)互質,並且e小於 ( p − 1 ) ( q − 1 ) (p-1)(q-1) (p−1)(q−1)。
- 用以下這個公式計算d: d ∗ e m o d ( p − 1 ) ( q − 1 ) ≡ 1 d*e \mod (p-1)(q-1) \equiv 1 d∗emod(p−1)(q−1)≡1。
- 將p和q的記錄銷燬。
這裡得到的(N, e)是公鑰,(N, d)是私鑰。
下面展示RSA的實現細節
import time
def range_prime(start, end):
l = list()
for i in range(start, end+1):
flag = True
for j in range(2, int(i**0.5)+1):
if i % j == 0:
flag = False
break
if flag:
l.append(i)
return l
def generate_keys(p, q):
numbers = range_prime(10, 100)
N = p * q
C = (p-1) * (q-1)
e = 0
for n in numbers:
if n < C and C % n > 0:
e = n
break
if e == 0:
raise BaseException("e not found")
d = 0
for n in range(2, C):
if(e * n) % C == 1:
d = n
break
if d == 0:
raise BaseException("d not found")
return (N, e), (N, d)
def quick_algorithm(a, b, c):
a = a % c
ans = 1
while b != 0:
if b & 1:
ans = (ans * a) % c
b >>= 1
a = (a * a) % c
return ans
def encrypt(m, key):
C, x = key
# return quick_algorithm(m, x, C)
return (m ** x) % C
def decrypt(m, key):
return encrypt(m, key)
def ord2hex(num):
return hex(num)
if __name__ == '__main__':
start = int(1e3)
end = int(1e5)
prime_list = []
count = 0
while len(prime_list) < 2:
if count > 5:
raise RecursionError("達到最大次數")
prime_list = range_prime(start, end)
a = prime_list[0]
b = prime_list[-1]
print(a, b)
time1 = time.time()
print("開始產生金鑰對")
public_key, private_key = generate_keys(a, b)
print("私鑰:", private_key)
print("公鑰:", public_key)
time2 = time.time()
print("金鑰對生成結束,耗時:{}s".format(time2-time1))
ord_list = []
encode_list = []
s_input = input("請輸入要加密的字串:")
time3 = time.time()
print("開始加密")
for s in s_input:
s_ord = ord(s)
s_encode = encrypt(s_ord, public_key)
ord_list.append(s_ord)
encode_list.append(s_encode)
time4 = time.time()
print("加密完成,耗時:{}s".format(time4-time3))
# print(ord_list)
print(encode_list)
print("原資料:", [ord2hex(num) for num in ord_list])
print("加密後的資料:", ":".join([ord2hex(num) for num in encode_list]))
print("開始解密")
time5 = time.time()
decode_list = []
for num_encode in encode_list:
ord_decode = decrypt(num_encode, private_key)
decode_list.append(ord_decode)
time6 = time.time()
print("解密完成,耗時:{}s".format(time6-time5))
print("解密後的資料:", [ord2hex(num) for num in decode_list])
print("轉化為字串:", [chr(num) for num in decode_list])
相關文章
- RSA演算法原理(二)演算法
- RSA演算法原理(一)演算法
- RSA公鑰回密演算法原理演算法
- RSA演算法原理——(3)RSA加解密過程及公式論證演算法解密公式
- [數學趣味001]RSA演算法原理及示例演算法
- RSA 數學原理
- RSA的傻瓜原理
- RSA演算法演算法
- 非對稱加密技術- RSA演算法數學原理分析加密演算法
- RSA加密演算法加密演算法
- RSA演算法(一)演算法
- RSA演算法簡介演算法
- RSA演算法詳解演算法
- [轉載]RSA演算法演算法
- RSA加密原理&密碼學&HASH加密密碼學
- 非對稱演算法----RSA演算法演算法
- RSA演算法之學習演算法
- # RSA 公鑰加密演算法加密演算法
- RSA演算法,自己的理解!演算法
- JavaScript逆向之RSA演算法JavaScript演算法
- 非對稱加密--RSA原理淺析加密
- RSA加密解密原理深度剖析(附CTF中RSA題型實戰分析)加密解密
- 非對稱加密演算法-RSA演算法加密演算法
- RSA演算法基礎->實踐演算法
- 經典加密演算法入門-RSA加密演算法
- PHP RSA2 簽名演算法PHP演算法
- PHP中RSA加密演算法的使用PHP加密演算法
- RSA演算法與Python實現演算法Python
- Java實現AES和RSA演算法Java演算法
- RSA演算法以及數學基礎演算法
- RSA加密演算法的簡單案例加密演算法
- RSA 演算法是如何誕生的演算法
- RSA演算法應用及證明演算法
- RSA演算法揭秘:加密世界的守護者演算法加密
- 58同城的登入(RSA演算法)演算法
- 公開金鑰演算法-RSA-note演算法
- RSA非對稱加密演算法淺析加密演算法
- RSA 演算法和另類攻擊方式演算法