轉發註明出處:http://www.cnblogs.com/0zcl/p/6120389.htmlhtml
1976年之前,全部的加密方法都是同一種模式:python
(1)甲方選擇某一種加密規則,對信息進行加密;算法
(2)乙方使用同一種規則,對信息進行解密。編程
因爲加密和解密使用一樣規則(簡稱"密鑰"),這被稱爲"對稱加密算法"(Symmetric-key algorithm)。安全
這種加密模式有一個最大弱點:甲方必須把加密規則告訴乙方,不然沒法解密。保存和傳遞密鑰,就成了最頭疼的問題。網絡
1976年,兩位美國計算機學家Whitfield Diffie 和 Martin Hellman,提出了一種嶄新構思,能夠在不直接傳遞密鑰的狀況下,完成解密。這被稱爲"Diffie-Hellman密鑰交換算法"。這個算法啓發了其餘科學家。人們認識到,加密和解密可使用不一樣的規則,只要這兩種規則之間存在某種對應關係便可,這樣就避免了直接傳遞密鑰。app
這種新的加密模式被稱爲"非對稱加密算法"。dom
(1)乙方生成兩把密鑰(公鑰和私鑰)。公鑰是公開的,任何人均可以得到,私鑰則是保密的。ide
(2)甲方獲取乙方的公鑰,而後用它對信息加密。函數
(3)乙方獲得加密後的信息,用私鑰解密。
若是公鑰加密的信息只有私鑰解得開,那麼只要私鑰不泄漏,通訊就是安全的。
1977年,三位數學家Rivest、Shamir 和 Adleman 設計了一種算法,能夠實現非對稱加密。這種算法用他們三我的的名字命名,叫作RSA算法。從那時直到如今,RSA算法一直是最廣爲使用的"非對稱加密算法"。絕不誇張地說,只要有計算機網絡的地方,就有RSA算法。
這種算法很是可靠,密鑰越長,它就越難破解。根據已經披露的文獻,目前被破解的最長RSA密鑰是768個二進制位。也就是說,長度超過768位的密鑰,還沒法破解(至少沒人公開宣佈)。所以能夠認爲,1024位的RSA密鑰基本安全,2048位的密鑰極其安全。
RSA算法須要一些數學知識,不過別慫,不難的。我總結了一下,大概須要如下三部分的知識:
接下來講下每一個部分的內容:
一、互質關係:若是兩個正整數,除了1之外,沒有其餘公因子,咱們就稱這兩個數是互質關係(coprime)。好比,15和32沒有公因子,因此它們是互質關係。這說明,不是質數也能夠構成互質關係。
二、先說下 歐拉函數:φ(n)爲比n小但與n互素的正整數個數,稱爲n的歐拉函數。對任一素數p, 有φ(n)=p-1,而對於兩個不一樣的素數p和q,則對n=pq,能夠證實φ(n)=φ(pq)=(p-1)(q-1)=φ(p)*φ(q)
三、模反元素:如何求模反元素(逆元),用展轉相除法,我在上一篇博客<信息安全-4:公鑰密碼體制之揹包算法[原創]>有說,看了必定會懂的!
上面3點必定要GET,否則不用往下看了~~
RSA算法可概括以下:
上面過程很重要!!! 剛開始看會有點懵逼,看下面的例子,必定會懂!
咱們經過一個例子,來理解RSA算法。假設Alice想發送明文9726給Bob,這之間的過程是怎樣的?又是怎樣生成公鑰和私鑰呢?
(1)Bob生成密鑰
Bob選擇兩個互異素數p=101和q=113,計算:n=pq=101*113=11413, φ(n)=(p-1)(q-1)=100*112=11200
因爲加密密鑰e必須與φ(n)沒有公因子,假設Bob隨機選擇了e=3533,則用展轉相除法可求得: d=e-1=3533-1 mod 11200=6597
因而Bob公佈他的公鑰KU={3533, 11413}, 將私鑰KR={6597, 11413}保密。
(2)Alice加密信息
因爲Bob的公鑰是公開的,任何人均可獲得,所以Alice使用Bob的公鑰來加密即將發送給Bob的明文信息。
Alice計算: 97263533 mod 11413=5761, 而後在一個信道上發送密文5761.
(3)Bob解密密文
當Bob接收到密文5761時,他用他的私鑰進行解密。
Bob計算: 57616597 mod 11413=9726, 這樣Bob就獲得Alice發給他的明文信息了!!!
流程圖
我畫的流程圖網址: https://www.processon.com/diagraming/583fb2c0e4b0d0d77bcfa514
ReadMe:
源代碼
1 #RSA加密算法 2 3 import random 4 # p,q是兩個不一樣的素數n=pq,按理說應該隨機產生,這裏我用p=101,q=103爲例 5 6 P = 101 7 Q = 113 8 N = P * Q 9 global _E # 把逆元定義爲全局變量,才能在解密模塊調用 10 _E = 0 #初始爲0 11 12 #歐拉公式:若是n是質數,則 φ(n)=n-1 。由於質數與小於它的每個數,都構成互質關係 13 F = (P-1) * (Q-1) 14 15 16 #求最大公約數,若最大公約數是1,且m,n>1,m與n不等,則說明m,n互質 17 def comm_div(m, n): #m>n 18 temp = m % n 19 while(temp != 0): 20 m = n 21 n = temp 22 temp = m % n 23 if n == 1: #說明互質,返回True 24 return True 25 26 27 # 在1-9999之間隨機選擇一個整數e,條件是1< e < F,且e與F 互質 28 # 互質即說明e,F的公因子有且僅有1 29 def e_product(): 30 while True: 31 rand = random.randrange(2, F) 32 if comm_div(F, rand): 33 e = rand 34 return e 35 36 37 #用展轉相除法求質數e關於歐拉公式F的逆元 38 def _e_product(e, F): 39 a_list = [] 40 m = F 41 n = e 42 temp = m % n 43 44 while (temp != 0): 45 a = (m - temp) / n 46 a_list.append(a) 47 m = n 48 n = temp 49 temp = m % n 50 print("a_list:", a_list) 51 a_list.reverse() #逆序 52 print("a_list_reverse:", a_list) 53 b_list = [] 54 b_list.append(1) 55 b_list.append(a_list[0]) 56 print("(最初插入的兩個1及a_list[0])b_list:", b_list) 57 for i in range(len(a_list)-1): 58 b = b_list[-1] * a_list[i+1] + b_list[-2] 59 b_list.append(b) 60 61 print("b_list", b_list) 62 #a_list存放的是商數,若是商數個數是偶數 b_list[-1]即爲所求逆元 63 #若爲奇數,F-b_list[-1]爲所求的逆元 64 if len(a_list) % 2 == 0: #偶數 65 return b_list[-1] 66 else: 67 return F - b_list[-1] 68 69 70 #傳入明文(數字)和公鑰,進行加密,返回密文 71 def core_encryption(clear_text, e, N): 72 clear = clear_text 73 for i in range(e-1): 74 clear_text = clear_text * clear 75 cipher_text = clear_text % N 76 return cipher_text 77 78 79 def encryption(clear_text): 80 clear_text = int(clear_text) 81 e = e_product() 82 print("隨機產生的e:%s" % e) 83 global _E #對全局變量進行從新賦值,須要global 84 _E = _e_product(e, F) 85 # print("逆元_e:", _E) 86 # print("逆元類型:",type(_E)) 87 print("公鑰KU:%d,%d\n私鑰KR:%d,%d" % (e,N, _E,N)) 88 cipher_text = core_encryption(clear_text,e,N) 89 return cipher_text 90 91 92 #根據以前加密生成的私鑰進行解密,因此必須先有加密才行的 93 def decryption(cipher_text, _e, N): 94 cipher_text = int(cipher_text) 95 cipher = cipher_text 96 # print(_e) 97 # print("逆元_e類型:",type(_e)) 98 for i in range(_e-1): 99 cipher_text = cipher_text * cipher 100 clear_text = cipher_text % N 101 return clear_text 102 103 104 if __name__ == "__main__": 105 while True: 106 print("必須先加密後解密!".center(50, "-")) 107 choice = input("Input E for encryption or D for decryption:") 108 if choice == "E": 109 clear_text = input("請輸入明文(只容許數字):") 110 if clear_text.strip().isalnum(): 111 print("加密成功!密文爲:%d" % encryption(clear_text)) 112 if choice == "D": 113 cipher_text = input("請輸入密文:") 114 if cipher_text.strip().isalnum(): 115 print("解密成功!明文爲:%d" % decryption(cipher_text, _E, N))
問題
在測試時我遇到了下面這個問題
1 C:\Python34\python3.exe C:/Users/Administrator/PycharmProjects/xingxi/playfair/RSA.py 2 --------------------必須先加密後解密!--------------------- 3 Input E for encryption or D for decryption:E 4 請輸入明文(只容許數字):9726 5 隨機產生的e:2147 6 a_list: [5.0, 4.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 2.0, 1.0, 1.0, 1.0] 7 a_list_reverse: [1.0, 1.0, 1.0, 2.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 4.0, 5.0] 8 (最初插入的兩個1及a_list[0])b_list: [1, 1.0] 9 b_list [1, 1.0, 2.0, 3.0, 8.0, 11.0, 19.0, 30.0, 49.0, 79.0, 128.0, 591.0, 3083.0] 10 公鑰KU:2147,11413 11 私鑰KR:3083,11413 12 加密成功!密文爲:5200 13 --------------------必須先加密後解密!--------------------- 14 Input E for encryption or D for decryption:D 15 請輸入密文:5200 16 Traceback (most recent call last): 17 File "C:/Users/Administrator/PycharmProjects/xingxi/playfair/RSA.py", line 116, in <module> 18 print("解密成功!明文爲:%d" % decryption(cipher_text, _E, N)) 19 File "C:/Users/Administrator/PycharmProjects/xingxi/playfair/RSA.py", line 99, in decryption 20 for i in range(_e-1): 21 TypeError: 'float' object cannot be interpreted as an integer 22 23 Process finished with exit code 1
如今已經解決了,問題出在了下面第6行代碼,rang()函數裏面不能是float型,只須要int(_e-1)轉型便可解決!
1 def decryption(cipher_text, _e, N): 2 cipher_text = int(cipher_text) 3 cipher = cipher_text 4 # print(_e) 5 # print("逆元_e類型:",type(_e)) 6 for i in range(_e-1): 7 cipher_text = cipher_text * cipher 8 clear_text = cipher_text % N 9 return clear_text
你可能會說,毛線,這麼簡單的坑你都跳(鄙視臉)。
好吧,這都怪我在這以前輸出了一條測試print("_e:%d" % _e),而後我運行時看到輸出的是整型,就蒙比了,心想:明明是int型,怎麼會爆錯說float型!!!這大概就是所謂的被本身挖的坑坑到懷疑人生吧~~
測試(爲了方便我往後再來看,一些打印測試我沒有去除)
1 C:\Python34\python3.exe C:/Users/Administrator/PycharmProjects/xingxi/playfair/RSA.py 2 --------------------必須先加密後解密!--------------------- 3 Input E for encryption or D for decryption:E 4 請輸入明文(只容許數字):9726 5 隨機產生的e:4031 6 a_list: [2.0, 1.0, 3.0, 1.0, 1.0, 17.0, 2.0, 1.0, 3.0] 7 a_list_reverse: [3.0, 1.0, 2.0, 17.0, 1.0, 1.0, 3.0, 1.0, 2.0] 8 (最初插入的兩個1及a_list[0])b_list: [1, 3.0] 9 b_list [1, 3.0, 4.0, 11.0, 191.0, 202.0, 393.0, 1381.0, 1774.0, 4929.0] 10 公鑰KU:4031,11413 11 私鑰KR:6271,11413 12 加密成功!密文爲:325 13 --------------------必須先加密後解密!--------------------- 14 Input E for encryption or D for decryption:D 15 請輸入密文:325 16 解密成功!明文爲:9726 17 --------------------必須先加密後解密!--------------------- 18 Input E for encryption or D for decryption:E 19 請輸入明文(只容許數字):25 20 隨機產生的e:6403 21 a_list: [1.0, 1.0, 2.0, 1.0, 75.0, 2.0] 22 a_list_reverse: [2.0, 75.0, 1.0, 2.0, 1.0, 1.0] 23 (最初插入的兩個1及a_list[0])b_list: [1, 2.0] 24 b_list [1, 2.0, 151.0, 153.0, 457.0, 610.0, 1067.0] 25 公鑰KU:6403,11413 26 私鑰KR:1067,11413 27 加密成功!密文爲:10272 28 --------------------必須先加密後解密!--------------------- 29 Input E for encryption or D for decryption:D 30 請輸入密文:10272 31 解密成功!明文爲:25 32 --------------------必須先加密後解密!--------------------- 33 Input E for encryption or D for decryption:
注:RSA算法背景參考自http://www.ruanyifeng.com/blog/2013/06/rsa_algorithm_part_one.html
博客參考書籍:信息安全概論(凌捷 謝贊福 編著)
接下來一個月信息安全方面可能最多會再寫一篇博客, 重心會放在人工智能和操做系統!fight!