11.9 简�的客户端认�¶
问题¶
ä½ æƒ³åœ¨åˆ†å¸ƒå¼�系统ä¸å®žçŽ°ä¸€ä¸ªç®€å�•的客户端连接认è¯�功能,å�ˆä¸�想åƒ�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.compare_digest() 函数。
使用这个函数å�¯ä»¥é�¿å…�é�到时间分æž�攻击,ä¸�è¦�用简å�•的比较æ“�作符(==)。
ä¸ºäº†ä½¿ç”¨è¿™äº›å‡½æ•°ï¼Œä½ éœ€è¦�将它集æˆ�到已有的网络或消æ�¯ä»£ç �ä¸ã€‚例如,对于sockets,æœ�务器代ç �应该类似下é�¢ï¼š
from socket import socket, AF_INET, SOCK_STREAM
secret_key = b'peekaboo'
def echo_handler(client_sock):
if not server_authenticate(client_sock, secret_key):
client_sock.close()
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䏿œ‰è¯¦ç»†ä»‹ç»�。