古典密碼:
代換密碼
(1)單表代換——愷撒密碼
愷撒密碼也叫做移位密碼,其實就是移位。
C=M+K(mod26)
(2)多表代換——維吉尼亞密碼
它有相對復雜的密鑰,但是如果密文足夠長,就會有大量重復的密文串出現,就可能被人猜出來。
(3)多字母代換——普萊費爾密碼
編制密碼表→整理明文→編寫密文(同行代換、同列代換、不同行不同列代換)
置換密碼
置換密碼又稱為換位密碼,它根據一定的規則重新排列明文,以便打破明文的結構特性。它的特點是保持明文的所有字符不變,只是利用置換打亂了明文字符的位置和次序,也就是說改變明文結構而非內容。
看了柵格換位和矩形換位,感嘆於古人的智慧!
弗拉姆密碼
一次一密弗拉姆密碼也叫一次一密密碼。但是在實際應用中它也存在着難點:
①產生大規模的隨機密鑰有困難。
②密鑰分配和保護存在困難
隨着計算機的發明,破解這些密碼變得容易。
現代密碼:
基本概念:
整數分解:
質因數
模運算:
有限域:
有限域亦稱伽羅瓦域(galois field),是僅含有限個元素的域,它是伽羅瓦(Galois,E.)於18世紀30年代研究代數方程根式求解問題時引出的.有限域的特征數必為某一素數p,因此它含的素域同構於Zp.若F是特征為p的有限域,則F中元素的個數為pⁿ,n為某一正整數.元素個數相同的有限域是同構的.因此,通常用GF(pⁿ)表示pⁿ元的有限域.GF(pⁿ)的乘法群是(pⁿ-1)階的循環群.有限域在近代編碼、計算機理論、組合數學等各方面有着廣泛的應用.
我在做一個區塊鏈的項目,這是部分成果:
有限域內的橢圓曲線:
1 class field(): 2 def __init__(self, num=0, prime=0): 3 if num < 0 or num >= prime: 4 error = 'Num{}not in field range 0 to {}'.format(num, prime) 5 raise ValueError(error) 6 self.num = num 7 self.prime = prime 8 9 def __eq__(self,other): 10 if other is None: 11 return False 12 return True 13 14 def __add__(self, other):#加法 15 if self.prime==other.prime: 16 return field((self.num+other.num)%self.prime,self.prime) 17 else: 18 raise ValueError(error) 19 20 def __sub__(self,other):#減法 21 if self.prime==other.prime: 22 return field((self.num-other.num)%self.prime,self.prime) 23 else: 24 return False 25 26 def __mul__(self,other):#數量乘法(要把乘數放后面(如果乘數是int型數據)) 27 if type(other)==int: 28 return field((self.num*other)%self.prime,self.prime) 29 if self.prime==other.prime: 30 return field((self.num*other.num)%self.prime,self.prime) 31 else: 32 return False 33 34 def __pow__(self,other):#指數運算 35 if type(other)==int: 36 return field((self.num**(other%self.prime))%self.prime,self.prime) 37 if self.prime==other.prime: 38 return field((self.num**other.num)%self.prime,self.prime) 39 else: 40 return False 41 42 #除法利用費馬小定理得出-->b**(-1)=b**(p-2) 43 #又有 a/b=a*(b**(-1)) 44 #得到 a/b=a*(b**(p-2)) 45 46 def __truediv__(self,other): 47 if type(other)==int: 48 return field((self.num*(other%self.prime)**(self.prime-2))%self.prime,self.prime) 49 if self.prime==other.prime: 50 return field((self.num*other.num**(self.prime-2))%self.prime,self.prime) 51 else: 52 return False 53 54 55 class point: 56 def __init__(self,x,y,a,b,prime=0): 57 if y**field(2,x.prime)!=x**field(3,x.prime)+a*x+b:#y**2=x**3+a*x+b 58 raise ValueError('({},{})is not on the curve'.format(x,y)) 59 self.x=x 60 self.y=y 61 self.a=a 62 self.b=b 63 self.prime=x.prime 64 65 def __eq__(self,other): 66 return self.x==other.x and self.y==other.y and self.a==other.a and self.b==other.b 67 68 def __add__(self, other): 69 x1=self.x 70 x2=other.x 71 y1=self.y 72 y2=other.y 73 a1=self.a 74 a2=other.a 75 b1=self.b 76 b2=other.b 77 if a1==a2 and b1==b2: 78 if x1.num!=x2.num: 79 x3=((y2-y1)/(x2-x1))**2-x1-x2 80 y3=(y2-y1)/(x2-x1)*(x1-x3)-y1 81 p3=point(x3,y3,a1,b1) 82 return p3 83 elif y1.num==0 and y2.num==0: 84 p3=(None,None,self.a,self.b) 85 return p3 86 elif y1.num==y2.num:#s=(3*x1**2+a1)//2*y1 87 x3=((field(3,self.prime)*x1**field(2,self.prime)+a1) 88 /field(2,self.prime)*y1)**field(2,self.prime)-field(2,self.prime)*x1 89 y3=((field(3,self.prime)*x1**field(2,self.prime)+a1)/field(2,self.prime)*y1)*(x1-x3)-y1 90 p3=point(x3,y3,a1,b1) 91 return p3 92 else: 93 raise 94 95 def __mul__(self, other): 96 temp = self 97 i=other.num 98 while i!=0: 99 temp=self+temp 100 i-=1 101 return temp
私鑰和公鑰:
私鑰是自己私有的,公鑰是公開的
公鑰是與私鑰算法一起使用的密鑰對的非秘密一半。公鑰通常用於加密會話密鑰、驗證數字簽名,或加密可以用相應的私鑰解密的數據。公鑰和私鑰是通過一種算法得到的一個密鑰對(即一個公鑰和一個私鑰),其中的一個向外界公開,稱為公鑰;另個自己保留,稱為私鑰。通過這種算法得到的密鑰對能保證在世界范圍內是唯一的。
使用這個密鑰對的時候,如果用其中一個密鑰加密一段數據,必須用另一個密鑰解密。如用公鑰加密數據就必須用私鑰解密,如果用私鑰加密也必須用公鑰解密,否則解密將不會成功
數字簽名:
發送報文時,發送方用一個哈希函數從報文文本中生成報文摘要,然后用發送方的私鑰對這個摘要進行加密,這個加密后的摘要將作為報文的數字簽名和報文一起發送給接收方,接收方首先用與發送方一樣的哈希函數從接收到的原始報文中計算出報文摘要,接着再公鑰來對報文附加的數字簽名進行解密,如果這兩個摘要相同、那么接收方就能確認該報文是發送方的。
個人理解:
加密過程: 報文--------(哈希)-------->摘要---------(私鑰)-------->數字簽名
發送 --------> 報文+數字簽名 -------->接受
接收方: 報文--------(哈希)-------->摘要1
數字簽名---------(公鑰)-------->摘要2
if 摘要1==摘要2:報文是發送方的;
新進展: