欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

验证客户端的链接合法性

程序员文章站 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。
os.urandom用法示例

 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用法示例

 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)
验证合法性链接_客户端