验证客户端的链接合法性
程序员文章站
2023-01-15 13:11:33
什么是验证合法性? 即在客户端想要和客户端进行链接的时候, 我们对客户端的身份进行验证是否合法. 我们如果想在分布式系统中实现一个简单的客户端链接认证功能, 但是又不想SSL那么复杂, 那么我们可以利用hmac + 加盐的方式来实现. 首先介绍两个方法,: 1. os.urandom(n) 该方法是 ......
什么是验证合法性?
即在客户端想要和客户端进行链接的时候, 我们对客户端的身份进行验证是否合法.
我们如果想在分布式系统中实现一个简单的客户端链接认证功能, 但是又不想ssl那么复杂, 那么我们可以利用hmac + 加盐的方式来实现.
首先介绍两个方法,:
1. os.urandom(n)
该方法是一种bytes类型的随机生成n个字节字符串的方法, 而且每次生成的值都不相同.
import hmac message = b'hello world' key = b'secret' h = hmac.new(key,message,digestmod='md5') print(h.hexdigest()) #比较两个密文是否相同,可以用hmac.compare_digest(密文、密文),然会true或者false。
2.hmac:
我们之前了解了用hashlib进行md5加密. 该方法其实和它差不多.
python自带的hmac模块实现了标准的hmac算法, 我们首先需要准备待计算的原始消息message,随机key和哈希算法, 这里采用md5算法.
具体使用方法如下:
import hmac message = b'hello world' key = b'secret' h = hmac.new(key,message,digestmod='md5') print(h.hexdigest()) #比较两个密文是否相同,可以用hmac.compare_digest(密文、密文),然会true或者false。
hmac输出的长度和原始哈希算法的长度一致。需要注意传入的key和message都是bytes
类型,str
类型需要首先编码为bytes
。
下面是利用hmac+加盐的方式来实现一个简单的客户端链接认证功能的例子:
from socket import * import hmac, os secret_key = b"hello, world!" def conn_auth(conn): """ 认证客户端链接 :param conn: :return: 验证结果 """ print("开始验证新连接的合法性") msg=os.urandom(32) # 生成一个32字节的随机字符串 conn.sendall(msg) h = hmac.new(secret_key, msg) # 生成密文 digest = h.digest() respone = conn.recv(len(digest)) return hmac.compare_digest(digest, respone) # 返回结果true或者false def data_handler(conn, bufsize=1024): """ 根据验证结果, 判断是否通信 :param conn: :param bufsize: :return: """ if not conn_auth(conn): print("链接不合法,关闭链接") conn.close() return print("链接合法, 开始通信") while true: data = conn.recv(bufsize) if not data:break conn.sendall(data.upper()) def server_handler(ip_port, bufsize, backlog=5): """ 只处理链接 :param ip_port: :param bufsize: :param backlog: :return: """ tcp_socket_server=socket(af_inet, sock_stream) tcp_socket_server.bind(ip_port) tcp_socket_server.listen(backlog) while 1: conn, addr = tcp_socket_server.accept() print("新连接[%s, %s]" %(addr[0],addr[1])) data_handler(conn, bufsize) if __name__ == '__main__': ip_port = ("127.0.0.1", 8808) bufsize = 1024 server_handler(ip_port, bufsize)
from socket import * import hmac, os secret_key = b"hello, world!" def conn_auth(conn): """ 接收服务端的随机码, 加密后发给服务端 :param conn: :return: """ msg = conn.recv(32) h = hmac.new(secret_key, msg) digest = h.digest() conn.sendall(digest) def client_handler(ip_port, bufsize): """ 创建tcp下的socket, 与服务端通信 :param ip_port: :param bufsize: :return: """ tcp_socket_client = socket(af_inet, sock_stream) tcp_socket_client.connect(ip_port) conn_auth(tcp_socket_client) while 1: data = input(">>>:").strip() if not data:continue if data == "quit":break tcp_socket_client.sendall(data.encode("utf-8")) respone = tcp_socket_client.recv(bufsize) print(respone.decode("utf-8")) if __name__ == '__main__': ip_port = ("127.0.0.1", 8808) bufsize = 1024 client_handler(ip_port, bufsize)