验证客户端的链接合法性

2018-11-28 08:53:06来源:博客园 阅读 ()

新老客户大回馈,云服务器低至5折

什么是验证合法性?

即在客户端想要和客户端进行链接的时候, 我们对客户端的身份进行验证是否合法. 

我们如果想在分布式系统中实现一个简单的客户端链接认证功能, 但是又不想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)
验证合法性链接_客户端

 

标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

上一篇:Python学习经验分享,希望对初学者有所帮助

下一篇:python简单入门