1. 验证客户端的合法性
# server.py import socket import hmac import os secret_key=b"xuanxuan" # 设置密钥,通讯双方肯定首先约定好的,其他的不知道这个约定密钥的肯定连不上server sk=socket.socket() sk.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) sk.bind(("127.0.0.1",8080)) sk.listen() conn, addr = sk.accept() def check_conn(conn): msg=os.urandom(32) # os.urandom(32)可以随机发送32位的字节(bytes类型),原理就是服务端利用密钥和msg使用hmac进行加密,把msg发给client # 如果client知道密钥,client端也对密钥和msg使用hmac加密,server端对比这两个加密后的结果,如果一致,则允许client端连接 conn.send(msg) # 服务端给客户端发送需要加密的对象msg,密钥是secret_key 如果client端事先知道约定的密钥,则使用hmac进行加密的结果一定是相同的 h=hmac.new(secret_key,msg) # hmac.new()用于指定需要后续加密的对象:secret_key 和 msg,两者都是bytes类型 digest=h.digest() # 进行加密 client_digest=conn.recv(1024) # 客户端对secret_key 和 msg使用hmac进行加密,把加密后的结果返回 return hmac.compare_digest(digest,client_digest) res=check_conn(conn) if res: conn.send(bytes("你好,客户端,我是服务器,你通过我的验证了,我们可以进行通话了".encode("utf-8"))) ret=conn.recv(1024).decode("utf-8") print(ret) conn.close() else: print("客户端不合法,我不要和你通信,我要关闭连接") conn.close() sk.close()
# client.py import socket import hmac secret_key=b"xuanxuan" # 合法的客户端,肯定知道它要连接的server端的密钥 sk=socket.socket() sk.connect(("127.0.0.1",8080)) msg=sk.recv(1024) # 接收server端发送来的msg 需要对msg进行加密(双方还有个密钥) h=hmac.new(secret_key,msg) # hmac.new()指定需要加密的对象 msg 和 密钥 client_digest=h.digest() sk.send(client_digest) ret=sk.recv(1024).decode("utf-8") # 如果客户端不合法,服务端打印”客户端不合法“然后直接中断连接 print(ret) # 如果客户端合法,就会收到server端的send()信息,可以正常通信了 sk.send(bytes("哈哈哈,好的,信息已收到~".encode("utf-8"))) # client端收到server端的send之后,给server端回一个收到啦 sk.close()
运行结果: