問題
你想在分布式系統中實現乙個簡單的客戶端連線認證功能,又不想像ssl那樣的複雜。
解決方案
可以利用 hmac 模組實現乙個連線握手,從而實現乙個簡單而高效的認證過程。下面是**示例:
import hmac
import os
def client_authenticate(connection, secret_key):
'''authenticate client to a remote service.
connection represents a network connection.
secret_key is a key known only to both client/server.
'''message = connection.recv(32)
hash = hmac.new(secret_key, message)
digest = hash.digest()
connection.send(digest)
def server_authenticate(connection, secret_key):
'''request client authentication.
'''message = os.urandom(32)
connection.send(message)
hash = hmac.new(secret_key, message)
digest = hash.digest()
response = connection.recv(len(digest))
return hmac.compare_digest(digest,response)
基本原理是當連線建立後,伺服器給客戶端傳送乙個隨機的位元組訊息(這裡例子中使用了 os.urandom() 返回值)。 客戶端和伺服器同時利用hmac和乙個只有雙方知道的金鑰來計算出乙個加密雜湊值。然後客戶端將它計算出的摘要傳送給伺服器, 伺服器通過比較這個值和自己計算的是否一致來決定接受或拒絕連線。摘要的比較需要使用 hmac.cowww.cppcns.commpare_digest() 函式。 使用這個函式可以避免遭到時間分析攻擊,不要用簡單的比較操作符(==)。 為了使用這些函式,你需要將它整合到已有的網路或訊息**中。例如,對於sockets,伺服器**應該類似下面:
from socket import socket, af_inet, sock_stream
secret_key = b'peekaboo'
def echo_handler(client_sock):
ifubnkuaze not server_authenticate(client_sock, secret_key):
client_sock.close()
ubnkuaze return
while true:
msg = client_sock.recv(8192)
if not msg:
break
client_sock.sendall(msg)
def echo_server(address):
s = socket(af_inet, sock_stream)
s.bind(address)
s.listen(5)
while true:
c,a = s.accept()
echo_handler(c)
echo_server(('', 18000))
within a client, you would do this:
from socket import socket, af_inet, sock_stream
secret_key = b'peekaboo'
s = socket(af_inet, sock_stream)
s.connect(('localhost', 18000))
client_authenticate(s, secret_key)
s.send(b'hello world')
resp = s.recv(1024)
討論hmac 認證的乙個常見使用場景是內部訊息通訊系統和程序間通訊。 例如,如果你程式設計客棧編寫的系統涉及到乙個集群中多個處理器之間的通訊, 你可以使用本節方案來確保只有被允許的程序之間才能彼此通訊。 事實上,基於 hmac 的認證被 multiprocessing 模組使用來實現子程序直接的通訊。
還有一點需要強調的是連線認證和加密是兩碼事。 認證成功之後的通訊訊息是以明文形式傳送的,任何人只要想監聽這個連線線路都能看到訊息(儘管雙方的金鑰不會被傳輸)。
hmac認證演算法基於雜湊函式如md5和sha-1,關於這個在ietf rfc 2104中有詳細介紹。
訊息佇列的簡單實現(客戶端A,客戶端B)
下面是兩個相互通訊程序的簡單實現,乙個代表客戶端a,乙個代表客戶端b 客戶端a 傳送typeb型別的資料到客戶端b 讀取傳送到客戶端a的typea型別的資料 include include include include include include include include include...
使用Nginx配置客戶端實現SSL雙向認證
1.ca 與自簽名 建立相關目錄 mkdir ssl cd ssl製作 ca 私鑰 openssl genrsa out ca.key 2048製作 ca 根證書 公鑰 openssl req new x509 days 3650 key ca.key out ca.crt2.伺服器端證書 製作服務...
SGame 簡單客戶端
在sgame client目錄下提供了乙個game cli.go,提供了簡單的功能,包括註冊 登陸和登出 首先進入client目錄,然後編譯之 go build game cli.go game cli game cli h a string server ip default 127.0.0.1 ...