【问题标题】:Sending Encrypted Data Through Socket And Decrypting Doesn't Work通过套接字发送加密数据并且解密不起作用
【发布时间】:2019-04-26 05:03:12
【问题描述】:

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

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

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

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

【问题讨论】:

    标签: python-2.7 sockets encryption aes


    【解决方案1】:

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

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

    注意 Python 3 代码。 Python 2 对我来说已经死了。支持将于明年结束,因此请升级!

    server.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.')
    

    client.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)
    

    【讨论】:

    • 感谢您的回复。我会试试看会发生什么。另外,我知道 python 2.7 将停止支持,我的大多数其他程序都在运行 python 3。代码看起来不错,但让我进入这个的是大文件。我尝试了一个 64000 位 (8KB) 的侦听套接字,并且成功了,但我需要一种方法将文件拆分成块并将它们发送到重新组装。
    • @BaconBombz 更新了文件分块。
    • 感谢您的帮助。集成 Diffie-Hellman 密钥交换需要一段时间,但我让它工作了。另外,我并没有真正打算使用 sleep 来组织数据传输。我只是试着把界面做得更好一点,因为所有这些立即弹出的行看起来都不太好。
    • @BaconBombz 仅供参考,如果您没有像我一样定义协议,例如 send(b'abc')send(b'def') recv(100) 可以得到 b'a'b'ab' 或 @987654330 @ 或介于两者之间的任何东西。这就像读取文件...您需要换行符、空值或字节计数或某种方法来确定消息的开始和结束位置,并进行缓冲直到获得完整的消息。
    • @BaconBombz 另一个例子参见this answer
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-11
    • 2013-08-21
    • 1970-01-01
    • 2013-11-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多