凯撒密码
—-已知的最早的代换密码
—-对字母表中的每个字母,用它之后的第3(或者第n)个字母来代换
明文:a b c d e f g h i j k l m n o p q r s t u v w x y z
密文:D E F G H I J K L M N O P Q R S T U V W X Y Z A B C
明文:meet me after the toga party
密文:PHHW PH DIWHU WKH WRJD SDUWB
字母转化为对应的数字
C=E(p)=(p+3) mod 26
C=E(p)=(p+k) mod 26
p=D(C)=(C-k) mod 26
例子:(编译环境是Spyder3.4,下载地址是https://winpython.github.io/)
# -*- coding: utf-8 -*-
""" Created on Wed Dec 07 14:14:16 2016 @author: Administrator """
letter_list='ABCDEFGHIJKLMNOPQRSTUVWXYZ';
#加密函数
def Encrypt(plaintext,key):
ciphertext='';
for ch in plaintext: #遍历明文
if ch.isalpha():
#明文是否为字母,如果是,判断大小写,分别进行加密
if ch.isupper():
ciphertext+=letter_list[(ord(ch)-65+key) % 26]
else:
ciphertext+=letter_list[(ord(ch)-97+key) % 26].lower()
else:
#如果不为字母,直接添加到密文字符里
ciphertext+=ch
return ciphertext
#解密函数
def Decrypt(ciphertext,key):
plaintext='';
for ch in ciphertext:
if ch.isalpha():
if ch.isupper():
plaintext+=letter_list[(ord(ch)-65-key) % 26]
else:
plaintext+=letter_list[(ord(ch)-97-key) % 26].lower()
else:
plaintext+=ch
return plaintext
#Ö÷º¯Êý
user_input=input('加密请按D,解密请按E:');
while(user_input!='D' and user_input!='E'):
user_input=input('输入有误,请重新输入:')
key=input('请输入密钥:')
while(int(key.isdigit()==0)):
key=input('输入有误,密钥为数字,请重新输入:')
if user_input =='D':
plaintext=input('请输入明文:')
ciphertext=Encrypt(plaintext,int(key))
print ('密文为:\n%s' % ciphertext )
else:
ciphertext=input('请输入密文:')
plaintext=Decrypt(ciphertext,int(key))
print ( '明文为:\n%s\n' % ciphertext )
维吉尼亚密码
它是凯撒密码的改进。它对同一条信息中的不同字母用不同的密码进行加密。
例子: 如果使用关键字“BIG”,发件人将把信息按三个字母的顺序排列。则加密的信息每三个字母分别向后移动1、8、6位。
维吉尼亚例子:
# -*- coding: utf-8 -*-
""" Created on Wed Dec 07 14:48:29 2016 @author: Administrator """
letter_list='ABCDEFGHIJKLMNOPQRSTUVWXYZ';
def dealkey(key):
a=[]
for ch in key:
a.append(ord(ch.upper())-65)
return a
#加密函数
def Encrypt(plaintext,key):
ciphertext='';
i = 0
for ch in plaintext: #遍历明文
if i%len(get_list)==0:
i=0
#明文是否为字母,如果是,判断大小写,分别进行加密
if ch.isupper():
ciphertext+=letter_list[(ord(ch)-65+get_list[i]) % 26]
i+=1
else:
ciphertext+=letter_list[(ord(ch)-97+get_list[i]) % 26].lower()
i+=1
return ciphertext
#解密函数
def Decrypt(ciphertext,key):
plaintext='';
i = 0
for ch in ciphertext: #遍历密文
if i%len(get_list)==0:
i=0
#判断是否是大写
if ch.isupper():
plaintext+=letter_list[(ord(ch)-65-get_list[i]) % 26]
i+=1
else:
plaintext+=letter_list[(ord(ch)-97-get_list[i]) % 26].lower()
i+=1
return plaintext
user_input=input('加密请按D,解密请按E:');
while(user_input!='D' and user_input!='E'):
user_input=input('输入有误,请重新输入:')
key=input('请输入密钥:')
while(int(key.isalpha()==0)):
key=input('输入有误,密钥为字母,请重新输入:')
get_list=dealkey(key)
if user_input =='D':
plaintext=input('请输入明文:')
ciphertext=Encrypt(plaintext,get_list)
print ('密文为:\n%s' % ciphertext )
else:
ciphertext=input('请输入密文:')
plaintext=Decrypt(ciphertext,get_list)
print ( '明文为:\n%s\n' % plaintext )
RSA加密算法
1977年,由Rivest(李维斯特)、Shamir(萨莫尔)和Adleman(阿德曼)提出,1978年在MIT公布
是一种分组加密算法
明文和密文是0~n-1之间的正整数
应用最广泛的公钥密码算法,是操作系统安全中必不可少的加密解密算法。
数学基础
Euler(欧拉)定理
大整数因子分解的困难性
概念一:乘法逆元
如果gcd(a,b)=c,则存在m,n,使得c = ma + nb,称呼这种关系为a、b组合整数c,m,n称为组合系数。
当c=1时,有 ma + nb = 1 ,此时可以看出m是a模b的乘法逆元,n是b模a的乘法逆元。
gcd为求最大公约数函数
在有限域 中求e 的乘法逆元(截几张PPT的图【捂脸】)
测试例子:
p=11,q=13,e=7,
明文:85
密文:123
p=7,q=17,e=5,
明文:19
密文:66
用Python的简单例子:
import math
def prime_test(prime):
#判断一个数是不是素数
n=int(prime)
if n<1:
return False
for i in range(2,int(math.sqrt(n)+1)):
if n%i==0:
return False
return True
def gcd(a,b):
#求两个数的最大公约数
if a%b ==0:
return b
else:
return gcd(b,a%b)
def multip_inverse(e,fn):
A=0
B=1
m=fn
b=e
Q=m/b
R=m%b
if R>1:
X=A-Q*B
A=B
B=X
m=b
b=R
return
if R==1:
X=A-Q*B
return X%fn
#主程序
while True:
p=int(raw_input("请输入一个素数p:"))
if prime_test(p) == False:
print "输入的不是素数,请重新输入!"
continue
q=int(raw_input("请输入一个素数q:"))
if prime_test(q) == False:
print "输入的不是素数,请重新输入!"
continue
n=p*q
fn=(p-1)*(q-1)
print " p = ",p
print " q = ",q
print " n = p * q = ",n
print "fn = (p-1)*(q-1) = ",fn
e=int(raw_input("请输入一个数字e:(1<e<fn)且e,fn互为质数:"))
if e<=1 or e>=fn:
print "输入的e的范围无效:(1<e<%d)请重新输入!",fn
continue
if gcd(e,fn)!=1:
print "%d 与 %d 不是互为质数"%(e,fn)
continue
d=multip_inverse(e,fn)
print "公钥为(e.n)为;(%d,%d)" %(e,n)
print "密钥为(d,n)为:(%d,%d)" %(d,n)
print '*'*50
while True:
message=int(raw_input("请输入你要加密的数字明文message(1<=message<n)"))
if message <1 or message>=n:
print "message必须小于n,请重新输入"
continue
print "message = ",message
print "现在对message进行加密..."
print "\t加密公式为:cipher = (message ** e) % n"
cipher = (message ** e) % n
print "加密后的密文cipher为:",cipher
print "RSA加密成功!"
print '*'*50
print "正在对cipher进行解密..."
print "\t解密公式为:plain_text=(cipher ** d) % n"
plain_text = (cipher ** d) % n
print "解密后的明文 plain_text为:",plain_text
if message == plain_text:
print "解密成功!"
else:
print "解密失败!"
print '*'*50
break
结果截图:
RSA算法原理:
http://www.ruanyifeng.com/blog/2013/06/rsa_algorithm_part_one.html