通过socket发送加密数据并解密不起作用

问题描述 投票:0回答:2

我正在创建一个简单的加密软件。我目前遇到的问题是通过套接字发送加密的 aes 文件数据不起作用。在接收端,应该写入的文件是空的。我已经检查了我的代码很长一段时间,但无法解决它。

我做了一个没有联网的版本。 我已经能够在不同版本上发送最大 8 KB 的小文件

我的程序是基于功能的,因此程序从主菜单分支到其他菜单和功能。由于有一点跳跃,最好显示所有代码。 https://github.com/BaconBombz/Dencryptor/blob/Version-2.0/Dencryptor.py

套接字连接,并发送所有需要的数据。然后,文件被 AES 加密并通过套接字发送。接收端将加密数据写入文件并解密。程序会说文件已发送,但在接收端,程序会抛出一个结构错误,因为应该包含加密数据的文件是空的。

python-2.7 sockets encryption aes
2个回答
4
投票

代码太不最小,所以这里是下载未加密文件的最小示例。此外,TCP 是一种流协议,使用睡眠来分离数据是不正确的。相反,为字节流定义一个协议。这是我的示例的协议:

  1. 打开连接。
  2. 发送 UTF-8 编码的文件名,后跟换行符。
  3. 以十进制发送编码文件大小,后跟换行符。
  4. 发送文件字节。
  5. 关闭连接。

请注意,这是 Python 3 代码,因为 Python 2 已过时并且支持已结束。

服务器.py

from socket import *
import os

CHUNKSIZE = 1_000_000

# Make a directory for the received files.
os.makedirs('Downloads',exist_ok=True)

sock = socket()
sock.bind(('',5000))
sock.listen(1)

with sock:
    while True:
        client,addr = sock.accept()

        # Use a socket.makefile() object to treat the socket as a file.
        # Then, readline() can be used to read the newline-terminated metadata.
        with client, client.makefile('rb') as clientfile:
            filename = clientfile.readline().strip().decode()
            length = int(clientfile.readline())
            print(f'Downloading {filename}:{length}...')
            path = os.path.join('Downloads',filename)

            # Read the data in chunks so it can handle large files.
            with open(path,'wb') as f:
                while length:
                    chunk = min(length,CHUNKSIZE)
                    data = clientfile.read(chunk)
                    if not data: break # socket closed
                    f.write(data)
                    length -= len(data)

            if length != 0:
                print('Invalid download.')
            else:
                print('Done.')

客户端.py

from socket import *
import os

CHUNKSIZE = 1_000_000

filename = input('File to upload: ')

sock = socket()
sock.connect(('localhost',5000))
with sock,open(filename,'rb') as f:
    sock.sendall(filename.encode() + b'\n')
    sock.sendall(f'{os.path.getsize(filename)}'.encode() + b'\n')

    # Send the file in chunks so large files can be handled.
    while True:
        data = f.read(CHUNKSIZE)
        if not data: break
        sock.sendall(data)

0
投票

这里是对 Mark Tolonen 原始代码的基本加密改编。 客户

from socket import *
import os
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import padding

CHUNKSIZE = 1_000_000
HOST = 'localhost'  # The server's hostname or IP address
PORT = 101        # The port used by the server

filename = input('File to upload: ')

# Function to encrypt data
def encrypt_data(data, key):
    iv = os.urandom(16)
    padder = padding.PKCS7(128).padder()
    data = padder.update(data) + padder.finalize()
    cipher = Cipher(algorithms.AES(key), modes.CBC(iv), backend=default_backend())
    encryptor = cipher.encryptor()
    return iv + encryptor.update(data) + encryptor.finalize()

# Key for encryption (must be the same on the server)
key = b'1234567891234567'

sock = socket()
sock.connect((HOST, PORT))
with sock, open(filename, 'rb') as f:
    # Send filename and file size
    sock.sendall(filename.encode() + b'\n')
    sock.sendall(f'{os.path.getsize(filename)}'.encode() + b'\n')

    # Read file content
    file_data = f.read()
    # Encrypt file data
    encrypted_file_data = encrypt_data(file_data, key)
    # Send encrypted file data in chunks
    while encrypted_file_data:
        sock.sendall(encrypted_file_data[:CHUNKSIZE])
        encrypted_file_data = encrypted_file_data[CHUNKSIZE:]

服务器

from socket import *
import os
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import padding

CHUNKSIZE = 1_000_000
PORT = 101        # The port used by the server

# Make a directory for the received files if it doesn't exist
download_dir = 'Downloads'
os.makedirs(download_dir, exist_ok=True)

# Key for decryption (must be the same as on the client)
key = b'1234567891234567'

sock = socket()
sock.bind(('', PORT))
sock.listen(1)

with sock:
    while True:
        client, addr = sock.accept()

        with client, client.makefile('rb') as clientfile:
            filename = clientfile.readline().strip().decode()
            length = int(clientfile.readline())
            print(f'Downloading {filename}:{length}...')
            path = os.path.join(download_dir, filename)

            # Decrypt the received file data
            iv = clientfile.read(16)
            cipher = Cipher(algorithms.AES(key), modes.CBC(iv), backend=default_backend())
            decryptor = cipher.decryptor()

            with open(path, 'wb') as f:
                while length:
                    chunk = min(length, CHUNKSIZE)
                    data = clientfile.read(chunk)
                    if not data:
                        break  # socket closed
                    # Decrypt and write data to the file
                    decrypted_data = decryptor.update(data) + decryptor.finalize()
                    f.write(decrypted_data)
                    length -= len(data)

            if length != 0:
                print('Invalid download.')
            else:
                print('Done.')


© www.soinside.com 2019 - 2024. All rights reserved.