古典密码:
代换密码
(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:报文是发送方的;
新进展: