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:
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
