• Python 之网络编程之socket(3)hashlib模块


     

     hashlib模块

    #hashlib 这个模块是一堆加密算法的集合体,哈希算法的加密方式不止一种

    httpswww.cmd5.com md5解密

    # 应用场景在需要效验功能时使用

        用户密码的 = 加密,解密

        相关效验的 = 加密,解密

    #哈希算法也叫摘要算法,相同的数据始终得到相同的输出,不同的数据得到不同的输出。

    #(1)哈希将不可变的任意长度的数据,变成具有固定长度的唯一值

    (2) 字典的键值对映射关系是通过哈希计算的,哈希存储的数据是散列(无序)

    1. hashlib基本用法

    #例:

    import hashlib
    ##基本用法使用md5加密
    # (1)创建一个md5算法的对象
    hs = hashlib.md5()
    
    # (2)把想要加密的字符串通过update更新到hs这个对象
    # 参数是二进制字节流
    hs.update("hsz".encode("utf-8"))
    
    # (3)返回32位16进制的字符串
    res = hs.hexdigest()
    print(res)
    print(len(res),"")
    
    
    # (4)加盐 (加key只有你自己知道的明文) 目的: 增加密码的复杂度
    hs = hashlib.md5("hsz".encode("utf-8"))
    hs.update("123".encode("utf-8"))
    res = hs.hexdigest()
    print(res)
    
     
    
    #(5)动态加盐
    import random
    res = str(random.randrange(10000,100000))
    hs = hashlib.md5(res.encode())
    hs.update("aabbccdd".encode())
    res = hs.hexdigest()
    print(res)

    得到的结果为:(因为最后一个是动态加盐,加入的是随机值,所有最后一个值一直在变化)

    071a5dcfd09db850f1ff95131acc5f2c

    32

    72646ae443c21a820b2013262ea43f86

    27b72799df64dc1ceca1544ebdd82876

    # mod5 加密效率快 ,通用的加密方法,安全性稍差 位数是32位
    # sha  加密效率慢 ,算法相对来精密,安全性稍高

    ##基本用法使用sha系列密方法

    #例:

    import hashlib
    
     
    
    hs = hashlib.sha1()
    hs.update("hahaha_123".encode())
    res = hs.hexdigest()
    # 返回的加密的字符串长度是40位
    print(res)
    print(len(res),"")
    
    # 加密
    hs = hashlib.sha1("qwe".encode())
    hs.update("xx_qq123".encode())
    res = hs.hexdigest()
    print(res)
    
    # sha512
    hs = hashlib.sha512()
    hs.update("123456".encode())
    res = hs.hexdigest()
    #返回的字符串长度是128位
    print(res)
    print(len(res),"")

    输出结果为:

    f1817bcbd94c1b26f5e25ed375b92de337cfe38d

    40

    a2affd3f2502b5de251e6e7704a9d5d641e5338a

    ba3253876aed6bc22d4a6ff53d8406c6ad864195ed144ab5c87621b6c233b548baeae6956df346ec8c17f5ea10f35ee3cbc514797ed7ddd3145464e2a0bab413

    128

    ##基本用法使用hmac 加密

    #hmac 加密的算法更加不容易破解

    #例:

    import hashlib
    import hmac
    import os
    key = b"123"
    msg = b"456"
    
    # hmac里面的new方法相当于hashlib 创建对象和update 粘合在一起操作
    hm = hmac.new(key,msg)
    res = hm.hexdigest()
    print(res)
    print(len(res),"")
    
    # 随机返回长度为32位的二进制字节流(加盐)
    key = os.urandom(32)
    print(key)
    
    hs = hmac.new(key,msg)
    res = hs.hexdigest()
    print(res)
    print(len(res),"")

    由于后面两个加密时加盐,所有后面两个输出会一直在变化,这样安全性更强:

    #第一次运行:

    eade56028e252b77f7a0b8792e58b9cc

    32

    b'xb7wQxe4 5x15xcaxc3x7fUYxc3xcbx84<x10x7fxb1x8bxac_x04xf2x8bx948Cx1exa6x1ax10'

    fa9e0bceb2effd7adbcdb76b414ccf95

    32

    #第二次运行:

    eade56028e252b77f7a0b8792e58b9cc

    32

    b'xf6x08xf5x8d8+4xecxad[xc0#T^xedxb2{Vxa4xe9xb5xb7xe5>xecnxf6xd4xe3xe3xb6x87'

    fe78046eae3682d73ac9cfd838c4800c

    32

     

    2.文件效验

    首先需要创建两个文件:ceshi1.txt ceshi2.txt,然后都输入aaaaa,两个文件内容相同:

    #例:

    import hashlib
    # (1) 针对小文件的内容效验
    def check_md5(file):
        with open(file, mode="rb") as fp:
            hs = hashlib.md5()
            hs.update(fp.read())
    
        return hs.hexdigest()
    
    
    print(check_md5("ceshi1.txt"))
    print(check_md5("ceshi2.txt"))

    输出结果为:

    594f803b380a41396ed63dca39503542

    594f803b380a41396ed63dca39503542

     

    如果文件过大,是一次性读取不了的,所有(1)的方法只适合小文件的内容效验

    #例:

    import hashlib
    # (2) 针对于大文件的内容效验
    hs = hashlib.md5()
    hs.update("昨天晚上
    下雨了".encode())
    res = hs.hexdigest()
    print(res) # 894c4dd4b1f57472322db524e7b6a47f
    
    # 可以连续update 到hs对象进行字节流的拼接
    hs = hashlib.md5()
    hs.update("昨天晚上
    ".encode())
    hs.update("下雨了".encode())
    res = hs.hexdigest()
    print(res)

    输出结果为:

    894c4dd4b1f57472322db524e7b6a47f

    894c4dd4b1f57472322db524e7b6a47f

    #例:

    import hashlib
    
    # 方法一
    def check_md5_01(file):
        hs = hashlib.md5()
        with open(file,mode="rb") as fp:
            while True:
                content = fp.read(1)
                if content:
                    hs.update(content)
                else:
                    break
            return hs.hexdigest()
    
    print(check_md5_01("ceshi1.txt"))
    print(check_md5_01("ceshi2.txt"))
    
    print("========================")
    # 方法二
    import os
    def check_md5_02(file):
        hs = hashlib.md5()
        file_size = os.path.getsize(file)
        with open(file,mode="rb") as fp:
            while file_size:
                # read(1) 最多最多读一个,如果文件空了就不读了
                content = fp.read(1)
                hs.update(content)
                file_size -= len(content)
            return hs.hexdigest()
    
    print(check_md5_02("ceshi1.txt"))
    print(check_md5_02("ceshi2.txt"))

    输出结果为:

    594f803b380a41396ed63dca39503542

    594f803b380a41396ed63dca39503542

    ========================

    594f803b380a41396ed63dca39503542

    594f803b380a41396ed63dca39503542

     

    3.hashlibhmac加密socket应用一(效验秘钥)

    模拟客户端连接服务端需要秘钥的情况的过程

    服务端代码:

    import socket
    import hmac
    import os
    def auth(conn, secret_key):
        # 随机获取二进制的字节流
        msg = os.urandom(32)
        #print(msg)
    
        conn.send(msg)
        hm = hmac.new(secret_key, msg)
        res_serve = hm.hexdigest()
        # 接收客户端发给我的字符串
        res_client = conn.recv(1024).decode("utf-8")
        if res_serve == res_client:
            print("合法的链接")
            return True
        else:
            print("不合法的链接")
            return False
    
    sk = socket.socket()
    sk.bind(("127.0.0.1", 9009))
    sk.listen()
    
    conn,addr = sk.accept()
    secret_key = b"hszhahaha"
    
    if auth(conn,secret_key):
        # 如果返回真,可以接收客户发过来的各种请求
        print(conn.recv(1024).decode("utf-8"))
    
    # 收发数据逻辑.
    # ...
    
    # 四次挥手
    conn.close()
    # 退还端口
    sk.close()

    客户端代码:

    import socket
    import hmac
    
    def auth(sk, key):
        # 接收服务器发过来的随机二进制字节流
        msg = sk.recv(32)
        # print(msg)
        hm = hmac.new(key, msg)
        res = hm.hexdigest()
    
        # 把加密后的字符串发送给服务器
        sk.send(res.encode())
    
    sk = socket.socket()
    
    key = b"hszhahaha"
    sk.connect(("127.0.0.1", 9009))
    auth(sk,key)
    sk.send(b"download")
    sk.close()

    3.hashlibmd5加密socket应用二(验证登录)

    首先需要创建一个用户信息包括用户名和加密后的密码:

    解密的方式是已用户名为盐值,用密码+用户名进行md5加密

    userinfo.txt内存入这三个信息密码加密后存入文本:

     zhangsan 111
     li  222
     wangwu 333

    解密的内容如图方式:

    服务端代码为:

    import socket
    import json
    # zhangsan 111
    # li  222
    # wangwu 333
    
    sk = socket.socket()
    sk.connect(("127.0.0.1", 9005))
    
    # 收发数据的逻辑
    usr = input("请输入用户名:")
    pwd = input("请输入您的密码:")
    dic = {"username":usr,"password":pwd,"operate":"login"}
    
    # 把字典系列化成字符串
    json_dic = json.dumps(dic)
    
    #把字符串变成字节流
    bytes_msg = json_dic.encode("utf-8")
    sk.send(bytes_msg)
    
    # 接收服务器的返回值
    res_msg = sk.recv(1024).decode()
    
    # 反序列化成字典
    dic_code = json.loads(res_msg)
    if dic_code['code']:
        print("恭喜你,登录成功")
    else:
        print("抱歉,登录失败")

    客户端代码为:

    import socket
    import json
    import hashlib
    
    def get_md5_code(usr, pwd):
        hs = hashlib.md5(usr.encode())
        hs.update(pwd.encode())
        return hs.hexdigest()
    
    sk = socket.socket()
    sk.bind(("127.0.0.1", 9005))
    sk.listen()
    
    conn,addr = sk.accept()
    # 把接收的字节流变成字符串
    msg = conn.recv(1024).decode()
    
    # 反序列化字典
    dic = json.loads(msg)
    
    # 默认编辑用户不存在
    sign = False
    
    with open("userinfo.txt",mode="r",encoding="utf-8") as fp:
        for line in fp:
            usr,pwd = line.strip().split(":")
            if usr == dic['username'] and pwd == get_md5_code(dic['username'],dic['password']):
                res = {"code":1}
                res_msg = json.dumps(res).encode()
                conn.send(res_msg)
                # 该用户找到了,存在
                sign = True
                break
    if sign == False:
        res = {"code":0}
        res_msg = json.dumps(res).encode()
        conn.send(res_msg)
    
    conn.close()
    sk.close()

    #运行结果是,在客户端让其输入用户密码:

    #如果用户或密码错误会返回登录失败:

    #如果用正确的用户密码输入返回成功:

  • 相关阅读:
    天线设计相关性能参数
    为什么在晶振上并电阻?
    晶体谐振器 晶体振荡器 正确区分
    示波器入门之采样率、存储深度
    示波器你了解多少?存储深度是什么?
    数字时序:时钟信号、抖动、迟滞和眼图
    信号完整性与电源完整性的详细分析
    信号完整性入门笔记三---阻抗及影响阻抗的因素
    H5——条件注释
    H5——meta
  • 原文地址:https://www.cnblogs.com/hszstudypy/p/10992740.html
Copyright © 2020-2023  润新知