要求如下:
(1)A,B两端各生成公钥密钥对(PA,SA), 密钥对(PB,SB)。
(2)A端生成随机数N1,用B的公钥PB加密,并发送至B端,B端接受并用私钥SB解密,将解密数据N1’,发送回A端,A端验证N1与N1’是否相等,若相等,A通过对B的身份认证。
(3)B端生成随机数N2,用A的公钥PA加密,并发送至A端,A端接受并用私钥SA解密,将解密数据N2’,发送回B端,B端验证N2与N2’是否相等,若相等,B通过对A的身份认证。
(4)完成身份认证之后,用DES算法传送加一段儿随机密数据,并用MD5算法校验文件完整性。
实验步骤:
。。。。运行过程中记得导入所需要的包啊,黑屏终端会有提示信息的。。。。。。
。。。。用pip install 包名 来导入。。。。。。。。。。。。。。。。。。。。。
准备过程:
(1)在D盘下建立test目录,test目录下再建立A,B两个目录 ,如图:
(2)然后运行文件aaction.py生成公钥和私钥,然后把A目录下的公钥(public.pem)复制到B目录下,名字改为yourpublic.pem
(3)运行baction.py文件,将B下的公钥(public.pem)复制到A目录下并且把名字改为yourpublic.pem,这样就让A,B知道了对方的公钥,接下来就能用对方的公钥加密消息发送给对方,然后让对方用自己的私钥进行解密了。
上面步骤完成之后结果如下图:
实验过程:
(1)重新运行aaction.py文件
(2)然后再运行baction.py文件(一定要注意顺序)
这时再看aaction.py这边,如下图:
如果出现上面两张图则说明模拟rsa算法的双向验证完毕。
接下来在aaction.py的黑屏终端输入需要用des算法加密,并且让MD5生成报文摘要的数据
baction.py终端下如下图则说明收到的消息用des算法解密完成,并且经过MD5校验之后没有发现问题。有问题的话就会提示验证失败的消息。
代码奉上:
(1)aaction.py的代码如下
import socket
import rsa
import os
import random
import threading
import multiprocessing
from time import ctime,sleep
import binascii
from pyDes import des, CBC, PAD_PKCS5
import hashlib
def myserver(mypubaddr,mypriaddr,mybind):
#判断是否存在公钥私钥文件,不存在的话就生成文件
if os.path.exists(mypubaddr) == True:
print('File already exists')
else:
(pubkey, privkey) = rsa.newkeys(1024)
pub = pubkey.save_pkcs1()
pubfile = open(mypubaddr,'wb')
pubfile.write(pub)
pubfile.close()
pri = privkey.save_pkcs1()
prifile = open(mypriaddr,'wb')
prifile.write(pri)
prifile.close()
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(mybind)
server.listen(5)
print("服务器启动成功。。。")
while True:
clientSocket, clientAddress = server.accept()
print("%s---%s连接成功"%(str(clientSocket), clientAddress))
with open(mypriaddr) as privatefile:
p = privatefile.read()
privkey = rsa.PrivateKey.load_pkcs1(p)
data = clientSocket.recv(1024)
message = rsa.decrypt(data, privkey)
#发送给client的随机数生成的密文
clientSocket.send(message)
data = clientSocket.recv(1024)
data = data.decode('utf-8')
if data == 'success':
print("验证成功")
s1 = 'checksuccess'
return s1
else:
print("验证失败")
f1 = 'checkfail'
return f1
def myclient(conaddr,yourpubaddr):
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect(conaddr)
#生成随机验证数
message = str(random.randint(0,1000))
message = message.encode()
#读取保存的别人的公钥
with open(yourpubaddr) as publickfile:
p = publickfile.read()
pubkey = rsa.PublicKey.load_pkcs1(p)
'''
with open(r'D:\text\private.pem') as privatefile:
p = privatefile.read()
privkey = rsa.PrivateKey.load_pkcs1(p)
'''
#对随机验证数进行公钥加密
crypto = rsa.encrypt(message, pubkey)
#将公钥加密过的数据发送给接收方
data = crypto
client.send(data)
#接收对方发过来的数据并且与己方发送的message进行对比校验
while True:
info = client.recv(1024)
print(info.decode())
if message == info:
print("对server认证通过")
#client.send(data.encode("utf-8"))
check = str('success')
#print(check.encode("utf-8"))
client.send(check.encode('utf-8'))
print(check)
s1 = 'checksuccess'
return s1
else:
f1 = 'checkfail'
return f1
def clientagain(conaddr):
while True:
inputdata = input("请输入需要发送的数据:")
#用des算法加密
desEncryptData = des_encrypt(inputdata)
#用MD5生成摘要
md5EncryptData = md5encrypt(inputdata)
md5EncryptData = bytes(md5EncryptData, 'utf-8')
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect(conaddr)
#发送拼接的数据
client.sendall(desEncryptData)
client.send(" ".encode('utf-8'))
client.sendall(md5EncryptData)
def des_encrypt(s):
secret_key = '20171117'
iv = secret_key
k = des(secret_key, CBC, iv, pad=None, padmode=PAD_PKCS5)
en = k.encrypt(s, padmode=PAD_PKCS5)
return binascii.b2a_hex(en)
def md5encrypt(str):
#str = input("请输入需要用MD5加密的数据")
# 创建md5对象
hl = hashlib.md5()
# 此处必须声明encode
# 若写法为hl.update(str) 报错为: Unicode-objects must be encoded before hashing
hl.update(str.encode(encoding='utf-8'))
#print('MD5加密前为 :' + str)
#print('MD5加密后为 :' + hl.hexdigest())
return hl.hexdigest()
if __name__ == '__main__':
print("--------------------------------双向验证开始---------------------------------")
mypubaddr = r'D:\test\A\public.pem'
mypriaddr = r'D:\test\A\private.pem'
mybind = ('127.0.0.1', 8083)
check1 = myserver(mypubaddr,mypriaddr,mybind)
sleep(1)
conaddr = ("127.0.0.1", 8082)
yourpubaddr = r'D:\test\A\yourpublic.pem'
check2 = myclient(conaddr,yourpubaddr)
if (check1 == 'checksuccess') and (check2 == 'checksuccess'):
print("--------------------------------双向验证成功---------------------------------")
print("--------------------------------双向验证结束---------------------------------")
print("---------------------准备正式发送加密过的des和MD5数据---------------------------")
sleep(1)
clientagain(conaddr)
else:
print("--------------------------------双向验证失败---------------------------------")
print("--------------------------------双向验证结束---------------------------------")
baction.py的代码如下:
import socket
import rsa
import os
import random
import threading
import multiprocessing
from time import ctime,sleep
import binascii
from pyDes import des, CBC, PAD_PKCS5
import hashlib
def myserver(mypubaddr,mypriaddr,mybind):
#判断是否存在公钥私钥文件,不存在的话就生成文件
if os.path.exists(mypubaddr) == True:
print('File already exists')
else:
(pubkey, privkey) = rsa.newkeys(1024)
pub = pubkey.save_pkcs1()
pubfile = open(mypubaddr,'wb')
pubfile.write(pub)
pubfile.close()
pri = privkey.save_pkcs1()
prifile = open(mypriaddr,'wb')
prifile.write(pri)
prifile.close()
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(mybind)
server.listen(5)
print("服务器启动成功。。。")
while True:
clientSocket, clientAddress = server.accept()
print("%s---%s连接成功"%(str(clientSocket), clientAddress))
with open(mypriaddr) as privatefile:
p = privatefile.read()
privkey = rsa.PrivateKey.load_pkcs1(p)
data = clientSocket.recv(1024)
message = rsa.decrypt(data, privkey)
#发送给client的随机数生成的密文
clientSocket.send(message)
data = clientSocket.recv(1024)
data = data.decode('utf-8')
if data == 'success':
print("验证成功")
s1 = 'checksuccess'
return s1
else:
print("验证失败")
f1 = 'checkfail'
return f1
def myclient(conaddr,yourpubaddr):
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect(conaddr)
#生成随机验证数
message = str(random.randint(0,1000))
message = message.encode()
#读取保存的别人的公钥
with open(yourpubaddr) as publickfile:
p = publickfile.read()
pubkey = rsa.PublicKey.load_pkcs1(p)
'''
with open(r'D:\text\private.pem') as privatefile:
p = privatefile.read()
privkey = rsa.PrivateKey.load_pkcs1(p)
'''
#对随机验证数进行公钥加密
crypto = rsa.encrypt(message, pubkey)
#将公钥加密过的数据发送给接收方
data = crypto
client.send(data)
#接收对方发过来的数据并且与己方发送的message进行对比校验
while True:
info = client.recv(1024)
print(info.decode())
if message == info:
print("对server认证通过")
#client.send(data.encode("utf-8"))
check = str('success')
#print(check.encode("utf-8"))
client.send(check.encode('utf-8'))
print(check)
s1 = 'checksuccess'
return s1
else:
f1 = 'checkfail'
return f1
def serverAgain(mybind):
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(mybind)
server.listen(5)
print("服务器启动成功。。。")
while True:
clientSocket, clientAddress = server.accept()
print("%s---%s连接成功"%(str(clientSocket), clientAddress))
'''
data = clientSocket.recv(1024)
clientSocket.send(message)
'''
data = clientSocket.recv(1024)
data = data.decode('utf-8')
#对数据进行res和md5校验
check(data)
def des_descrypt(s):
secret_key = '20171117'
iv = secret_key
k = des(secret_key, CBC, iv, pad=None, padmode=PAD_PKCS5)
de = k.decrypt(binascii.a2b_hex(s), padmode=PAD_PKCS5)
return de
'''
str_de = des_descrypt(str_en)
print("解密后为:",str_de)
'''
def md5encrypt(de):
#str = input("请输入需要加密的数据")
# 创建md5对象
hl = hashlib.md5()
# 此处必须声明encode
# 若写法为hl.update(str) 报错为: Unicode-objects must be encoded before hashing
hl.update(de)
#print('MD5加密前为 :' + str)
#print('MD5加密后为 :' + hl.hexdigest())
return hl.hexdigest()
def check(data):
#分割字符串,前为des加密的字符串,后为md5报文摘要
list = data.split()
#des加密的字符串
s1 = list[0]
#md5报文摘要
s2 = list[1]
#des解密
de = des_descrypt(s1)
#解密数据生成报文摘要
remd5 = md5encrypt(de)
if s2 == remd5:
print("XXXXXXXXXXXXXXXXXXX收到的消息没有被修改,验证过程结束XXXXXXXXXXXXXXXXXXXXXXXX")
else:
print("XXXXXXXXXXXXXXXXXXXXXXXXXX传输信息可能被修改XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX")
if __name__ == '__main__':
print("--------------------------------双向验证开始---------------------------------")
conaddr = ("127.0.0.1", 8083)
yourpubaddr = r'D:\test\B\yourpublic.pem'
check2 = myclient(conaddr,yourpubaddr)
mypubaddr = r'D:\test\B\public.pem'
mypriaddr = r'D:\test\B\private.pem'
mybind = ('127.0.0.1', 8082)
check1 = myserver(mypubaddr,mypriaddr,mybind)
if (check1 == 'checksuccess') and (check2 == 'checksuccess'):
print("--------------------------------双向验证成功---------------------------------")
print("--------------------------------双向验证结束---------------------------------")
print("------------------------准备正式接收rsa和MD5数据-----------------------------")
serverAgain(mybind)
else:
print("--------------------------------双向验证失败---------------------------------")
print("--------------------------------双向验证结束---------------------------------")