Python学习日记(三十二) hmac检验客户端的合法性和

系统 1405 0

Hmac模块

其实这个模块类似hashlib模块,它能将一些重要的信息通过算法加密成密文,让信息更具有安全性。

关于hmac加密算法的了解:它的全名是哈希运算消息认证码(Hash-based Message Authentication Code),HMAC利用hash算法,以一个消息M和一个秘钥K作为输入,生成一个定长的消息摘要作为输出。HMAC算法利用已有的hash函数,关键问题是如何使用秘钥。

使用

            
              import
            
             hmac                     
            
              #
            
            
              这个模块和hashlib机制很相似
            
            
h = hmac.new(b
            
              '
            
            
              key
            
            
              '
            
            ,b
            
              '
            
            
              msg
            
            
              '
            
            )     
            
              #
            
            
              需要一个秘钥(bytes类型)和你想进行加密的bytes类型数据,前面为随机的key后面为一个消息
            
            
              print
            
            (h.digest())               
            
              #
            
            
              结果拿到一个密文 
            
            
              #
            
            
              b'\x18\xe3T\x8cY\xad@\xdd\x03\x90{z\xee\xe7\x1dg'
            
          

检验客户端合法性

如何确定这个客户端是该服务器的合法客户端呢?如果两边实现都讲好了他们的秘钥就可以利用hmac.compare_digest()方法去比较他们最后产生的密文到底是不是相同的,如果是那就是合法的就进行相应的操作,若不合法就直接关闭。

这里介绍一个新的os模块方法urandom(32)

            
              import
            
            
               os

            
            
              print
            
            (os.urandom(32))   
            
              #
            
            
              随机生成32位的字节
            
            
              #
            
            
              b'\xe2\x84:\x93\x82Q9\xff\x9e\x7f\x8a\x97)[\xedn\r\xa8\xf0v\x8b\xc0g\xbd\xe7\xeb\x0e\xa4\xf0\x80\x0c\x16'
            
          

利用这种'加盐'的方法我们就能让我们产生的秘钥具有不确定性,更加安全

检验合法的结果 :

Sever:

            
              import
            
            
               socket

            
            
              import
            
            
               hmac

            
            
              from
            
             os 
            
              import
            
            
               urandom
secret_key 
            
            = b
            
              '
            
            
              egg
            
            
              '
            
            
              #
            
            
              秘钥
            
            
sk =
            
               socket.socket()
sk.bind((
            
            
              '
            
            
              127.0.0.1
            
            
              '
            
            ,8090
            
              ))
sk.listen()


            
            
              def
            
            
               check_conn(conn):
    constant 
            
            = urandom(32
            
              )
    conn.send(constant)
    h 
            
            = hmac.new(secret_key,constant)                        
            
              #
            
            
              拿到一个密文对象
            
            
    sever_digest =
            
               h.digest()
    client_digest 
            
            = conn.recv(1024
            
              )
    
            
            
              return
            
            
               hmac.compare_digest(sever_digest,client_digest)

conn,addr 
            
            =
            
               sk.accept()

res 
            
            =
            
               check_conn(conn)

            
            
              if
            
            
               res:
    
            
            
              print
            
            (
            
              '
            
            
              合法的客户端!
            
            
              '
            
            )                                    
            
              #
            
            
              合法的客户端!
            
            
              #
            
            
              进行一系列操作
            
            
              #
            
            
              conn.close()
            
            
              pass
            
            
              else
            
            
              :
    
            
            
              print
            
            (
            
              '
            
            
              不合法的客户端!
            
            
              '
            
            
              )
    conn.close()
sk.close()
            
          

Client:

            
              import
            
            
               socket

            
            
              import
            
            
               hmac

secret_key 
            
            = b
            
              '
            
            
              egg
            
            
              '
            
            
              
sk 
            
            =
            
               socket.socket()
sk.connect((
            
            
              '
            
            
              127.0.0.1
            
            
              '
            
            ,8090
            
              ))
msg 
            
            = sk.recv(1024
            
              )

h 
            
            =
            
               hmac.new(secret_key,msg)
client_digest 
            
            =
            
               h.digest()
sk.send(client_digest)

sk.close()
            
          

那如果这个客户端它并不知道服务端的秘钥或者不知道服务端用的是HMAC进行的加密,那么它的结果很有可能是错误,给我们返回错误的客户端!

 

Socketsever模块

socketsever模块它能够实现多个客户端之间的交互

基本实现

Sever:

            
              import
            
            
               socketserver

            
            
              class
            
             Mysever(socketserver.BaseRequestHandler):                                 
            
              #
            
            
              一般情况下带Base都是作为父类,Request即请求,Handler就是处理
            
            
              def
            
            
               handle(self):
        
            
            
              print
            
            (self.request.recv(1024).decode(
            
              '
            
            
              utf-8
            
            
              '
            
            ))                          
            
              #
            
            
              self.request相当于一个conn
            
            
              if
            
            
              __name__
            
             == 
            
              '
            
            
              __main__
            
            
              '
            
            
              :
    sever 
            
            = socketserver.ThreadingTCPServer((
            
              '
            
            
              127.0.0.1
            
            
              '
            
            ,8080),Mysever)         
            
              #
            
            
              Thread线程
            
            
              #
            
            
              在一个程序里正常情况下只会有一个线程
            
            
              #
            
            
              一个线程就是调度CPU的最小单位
            
            
              #
            
            
              引入线程的概念去实现并发的效果
            
            
    sever.serve_forever()                                                       
            
              #
            
            
              表示我永远启用一个服务
            
          

Client:

            
              import
            
            
               socket
sk 
            
            =
            
               socket.socket()
sk.connect((
            
            
              '
            
            
              127.0.0.1
            
            
              '
            
            ,8080
            
              ))
sk.send(
            
            
              '
            
            
              hi
            
            
              '
            
            .encode(
            
              '
            
            
              utf-8
            
            
              '
            
            
              ))
sk.close()
            
          

Output:

            hi
          

有socketsever的原因就是我想同时处理多个客户端找我下载的请求,那socketsever只是在底层的基础上做了一层封装,帮我们实现了并发效果,所以没有'clientsever'这个概念,客户端只需要正常启用就好

实现多个客户端交互

Sever:

            
              import
            
            
               socketserver

            
            
              class
            
            
               Mysever(socketserver.BaseRequestHandler):
    
            
            
              def
            
            
               handle(self):
        
            
            
              while
            
            
               True:
            msg 
            
            = self.request.recv(1024).decode(
            
              '
            
            
              utf-8
            
            
              '
            
            
              )
            
            
            
              print
            
            
              (msg)
            info 
            
            = input(
            
              '
            
            
              <<<
            
            
              '
            
            ).encode(
            
              '
            
            
              utf-8
            
            
              '
            
            
              )
            self.request.send(
            
            
              '
            
            
              Sever:
            
            
              '
            
            .encode(
            
              '
            
            
              utf-8
            
            
              '
            
            ) +
            
               info)

            
            
              if
            
            
              __name__
            
             == 
            
              '
            
            
              __main__
            
            
              '
            
            
              :
    sever 
            
            = socketserver.ThreadingTCPServer((
            
              '
            
            
              127.0.0.1
            
            
              '
            
            ,8080
            
              ),Mysever)
    sever.serve_forever()
            
          

Client1:

            
              import
            
            
               socket
sk 
            
            =
            
               socket.socket()
sk.connect((
            
            
              '
            
            
              127.0.0.1
            
            
              '
            
            ,8080
            
              ))

            
            
              while
            
            
               True:
    msg 
            
            = input(
            
              '
            
            
              <<<
            
            
              '
            
            ).encode(
            
              '
            
            
              utf-8
            
            
              '
            
            
              )
    sk.send(
            
            
              '
            
            
              Client1:
            
            
              '
            
            .encode(
            
              '
            
            
              utf-8
            
            
              '
            
            ) +
            
               msg)
    
            
            
              print
            
            (sk.recv(1024).decode(
            
              '
            
            
              utf-8
            
            
              '
            
            
              ))
sk.close()
            
          

Client2:

            
              import
            
            
               socket
sk 
            
            =
            
               socket.socket()
sk.connect((
            
            
              '
            
            
              127.0.0.1
            
            
              '
            
            ,8080
            
              ))

            
            
              while
            
            
               True:
    msg 
            
            = input(
            
              '
            
            
              <<<
            
            
              '
            
            ).encode(
            
              '
            
            
              utf-8
            
            
              '
            
            
              )
    sk.send(
            
            
              '
            
            
              Client2:
            
            
              '
            
            .encode(
            
              '
            
            
              utf-8
            
            
              '
            
            ) +
            
               msg)
    
            
            
              print
            
            (sk.recv(1024).decode(
            
              '
            
            
              utf-8
            
            
              '
            
            
              ))
sk.close()
            
          

Output:

Python学习日记(三十二) hmac检验客户端的合法性和socketsever模块_第1张图片

  Python学习日记(三十二) hmac检验客户端的合法性和socketsever模块_第2张图片

  Python学习日记(三十二) hmac检验客户端的合法性和socketsever模块_第3张图片


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论