在這個程式中,我試圖通過 UDP 廣播向客戶端發送密鑰共享。我面臨的問題是將字串和位元組編碼為一條訊息,會產生許多錯誤。
我想從服務器向客戶端發送一個隨機 ID 和一個密鑰共享,其中包括索引(整數)和共享(16 位元組字串)。我在 id、index 和 share 之間添加了“:”,以便以后能夠在客戶端對其進行管理(通過將訊息拆分為多個部分)。
我嘗試將所有內容都轉換為字串,例如:
message = (str(id) ":" str(index) ":").encode('utf-16') str(share, 'utf-16'). 但這會導致客戶端的密鑰重建出現問題,其中密鑰共享應該是一個位元組字串,看起來像b"b'\xff\xfej\xb9\xdb\x8c&\x7f\x06\x87\x98Ig\xfc\x1eJ\xf6\xb5'".
然后我嘗試將 id 和索引編碼為 utf-16 并向客戶端發送訊息,然后對其進行解碼,但這并不能讓我重建密鑰并且我得到一個錯誤:ValueError: The encoded value must be an integer or a 16 byte string.
當我在客戶端解碼時,資料如下所示:f91f7e52-865d-49bc-bb45-ad80255e9ef9:5:?賛縵蜆????. 但是,解碼后的某些共享不包含分隔符,因此無法拆分。
有沒有辦法服務器可以在一條訊息(id、index、share)中發送以下所有資料,以便在客戶端正確分離?
服務器上所需的輸出將是(id = string,index = int,share = 16-byte string):
id = f91f7e52-865d-49bc-bb45-ad80255e9ef9
index = 5
share = b'\xff\xfej\xb9\xdb\x8c&\x7f\x06\x87\x98Ig\xfc\x1eJ\xf6\xb5'
服務器.py
from socket import *
import socket
import time
import uuid
from Crypto.Random import get_random_bytes
from Crypto.Protocol.SecretSharing import Shamir
server = socket.socket(AF_INET, SOCK_DGRAM)
server.setsockopt(SOL_SOCKET, SO_REUSEPORT, 1)
server.setsockopt(SOL_SOCKET, SO_BROADCAST, 1)
id = uuid.uuid4()
# generate 16-byte key
key = get_random_bytes(16)
# prepare k chunks of key
shares = Shamir.split(3, 5, key)
while True:
for index, share in shares:
message = (str(id) ":" str(index) ":").encode('utf-16') share
# send bytes
server.sendto(message, ('<broadcast>', 37020))
print("message sent!")
time.sleep(1)
客戶端.py
from socket import *
from Crypto.Protocol.SecretSharing import Shamir
audienceSocket = socket(AF_INET, SOCK_DGRAM)
audienceSocket.setsockopt(SOL_SOCKET, SO_REUSEPORT, 1)
audienceSocket.bind(('', 37020))
receivedShares = {}
reconstruct = []
while True:
# get data from sender
data, address = audienceSocket.recvfrom(1024)
decoded = data.decode('utf-16')
print("Decoded:", decoded)
id, index = decoded.split(":", 1)
index, share = index.split(":", 1)
share = share.encode('utf-16')
print(id)
print(index)
print(share)
if id not in receivedShares:
receivedShares[id] = set()
receivedShares[id].add((index, share))
print(receivedShares)
for shares in receivedShares:
if len(shares) >= 3:
for share in shares:
reconstruct.append(share)
# reconstrcut the key
key = Shamir.combine(reconstruct)
print("The key is:", key)
uj5u.com熱心網友回復:
UUID 可以編碼為 16 位元組的值,例如 4 位元組的整數,并且share長度為 16 位元組。因此,資料可以簡單地連接而無需分隔符并按它們的長度分隔,例如:
import uuid
from Crypto.Random import get_random_bytes
from Crypto.Protocol.SecretSharing import Shamir
id_sender = uuid.uuid4()
key = get_random_bytes(16)
shares = Shamir.split(3, 5, key)
for index_sender, share_sender in shares:
# Encode
message = id_sender.bytes index_sender.to_bytes(4, byteorder='big') share_sender
# Send message via socket
# Decode
id_receiver = uuid.UUID(bytes=message[:16])
index_receiver = int.from_bytes(message[16:20], byteorder='big')
share_receiver = message[20:]
print(id_sender == id_receiver, index_sender == index_receiver, share_sender == share_receiver) # True True True
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/447344.html
