我在python中创建了一个客户端-服务器模型。 这就像一个聊天室,但是我尝试使用来自cryptography.io的“ CTR”对消息进行加密。 当我在客户端中进行加密和解密时,它工作得很好,但是当我将其发送到服务器时,总是显示以下内容:
> > 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()
答案 0 :(得分:0)
您似乎先对消息进行编码然后对其进行加密,但是尝试对消息进行解码然后对其进行解密。如果先解密邮件然后再解码,则应该可以解决问题。
我认为将解密代码更改为此应该可以解决问题:
decryptor = cipher.decryptor()
ctt = decryptor.update(msg) + decryptor.finalize()
print(ctt)
txt = cct.decode()
print(txt)