Я создаю модель клиент-сервер в Python.Это похоже на чат, но я пытался зашифровать сообщения, используя "CTR" из cryptography.io.Когда я шифрую и дешифрую в клиенте, он работает довольно хорошо, но когда я отправляю его на сервер, всегда показываю это:
> > Task exception was never retrieved
> future: <Task finished coro=<handle_echo() done, defined at Server.py:43> exception=UnicodeDecodeError('utf-8', b'\x8f.\xcb', 0,
> 1, 'invalid start byte')>
> Traceback (most recent call last):
> File "Server.py", line 53, in handle_echo
> data = srvwrk.process(data)
> File "Server.py", line 25, in process
> txt = msg.decode()
> UnicodeDecodeError: 'utf-8' codec can't decode byte 0x8f in position 0: invalid start byte
Извините за мой английский, спасибо
клиент:
# Código baseado em https://docs.python.org/3.6/library/asyncio-stream.html#tcp-echo-client-using-streams
import asyncio
import socket
import os
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from cryptography.hazmat.backends import default_backend
conn_port = 8888
max_msg_size = 9999
class Client:
""" Classe que implementa a funcionalidade de um CLIENTE. """
def __init__(self, sckt=None):
""" Construtor da classe. """
self.sckt = sckt
self.msg_cnt = 0
def process(self, msg=b""):
""" Processa uma mensagem (`bytestring`) enviada pelo SERVIDOR.
Retorna a mensagem a transmitir como resposta (`None` para
finalizar ligação) """
self.msg_cnt +=1
backend = default_backend()
key = os.urandom(32)
iv = os.urandom(16)
cipher = Cipher(algorithms.AES(key), modes.CTR(iv), backend=backend)
print('Received (%d): %r' % (self.msg_cnt , msg.decode()))
print('Input message to send (empty to finish)')
new_msg = input().encode()
encryptor = cipher.encryptor()
ct = encryptor.update(new_msg) + encryptor.finalize()
print(ct)
return ct if len(ct)>0 else None
#
#
# Funcionalidade Cliente/Servidor
#
# obs: não deverá ser necessário alterar o que se segue
#
@asyncio.coroutine
def tcp_echo_client(loop=None):
if loop is None:
loop = asyncio.get_event_loop()
reader, writer = yield from asyncio.open_connection('127.0.0.1',
conn_port, loop=loop)
addr = writer.get_extra_info('peername')
client = Client(addr)
msg = client.process()
while msg:
writer.write(msg)
msg = yield from reader.read(max_msg_size)
if msg :
msg = client.process(msg)
else:
break
writer.write(b'\n')
print('Socket closed!')
writer.close()
def run_client():
loop = asyncio.get_event_loop()
loop.run_until_complete(tcp_echo_client())
run_client()
Это сервер: я пытался поместить 'utf-8' в txt = msg.decode () ... но всегда показываю одну и ту же ошибку
# Código baseado em https://docs.python.org/3.6/library/asyncio-stream.html#tcp-echo-client-using-streams
import asyncio
import codecs
import os
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from cryptography.hazmat.backends import default_backend
conn_cnt = 0
conn_port = 8888
max_msg_size = 9999
class ServerWorker(object):
""" Classe que implementa a funcionalidade do SERVIDOR. """
def __init__(self, cnt, addr=None):
""" Construtor da classe. """
self.id = cnt
self.addr = addr
self.msg_cnt = 0
def process(self, msg):
""" Processa uma mensagem (`bytestring`) enviada pelo CLIENTE.
Retorna a mensagem a transmitir como resposta (`None` para
finalizar ligação) """
self.msg_cnt += 1
txt = msg.decode()
print(txt)
decryptor = cipher.decryptor()
ctt = decryptor.update(msg) + decryptor.finalize()
print(ctt)
print('%d : %r' % (self.id,txt))
new_msg = txt.upper().encode()
return new_msg if len(new_msg)>0 else None
#
#
# Funcionalidade Cliente/Servidor
#
# obs: não deverá ser necessário alterar o que se segue
#
@asyncio.coroutine
def handle_echo(reader, writer):
global conn_cnt
conn_cnt +=1
addr = writer.get_extra_info('peername')
srvwrk = ServerWorker(conn_cnt, addr)
data = yield from reader.read(max_msg_size)
while True:
if not data: continue
if data[:1]==b'\n': break
data = srvwrk.process(data)
if not data: break
writer.write(data)
yield from writer.drain()
data = yield from reader.read(max_msg_size)
print("[%d]" % srvwrk.id)
writer.close()
def run_server():
loop = asyncio.get_event_loop()
coro = asyncio.start_server(handle_echo, '127.0.0.1', conn_port, loop=loop)
server = loop.run_until_complete(coro)
# Serve requests until Ctrl+C is pressed
print('Serving on {}'.format(server.sockets[0].getsockname()))
print(' (type ^C to finish)\n')
try:
loop.run_forever()
except KeyboardInterrupt:
pass
# Close the server
server.close()
loop.run_until_complete(server.wait_closed())
loop.close()
print('\nFINISHED!')
run_server()