AES加密通过TCP套接字传输文件;填充问题

时间:2013-03-31 15:53:02

标签: python sockets encryption tcp

我正在尝试使用带有AES 256的加密TCP套接字进行文件传输。

  • 如果我在没有加密的情况下传输文件,它可以正常工作。
  • 如果我向客户端或服务器发送小命令(例如'ipconfig'),加密工作正常。
  • 无论文件大小是多少,我都会收到以下错误消息:

    DecodeAES = lambda c, e: c.decrypt(base64.b64decode(e)).rstrip(PADDING)
      File "/usr/lib/python2.6/base64.py", line 76, in b64decode
        raise TypeError(msg)
    TypeError: Incorrect padding
    

我的编码和解码功能如下(hat变量是消息):

def AESENC(hat,typ):

    BLOCK_SIZE = 32
    PADDING = '{'
    pad = lambda s: s + (BLOCK_SIZE - len(s) % BLOCK_SIZE) * PADDING
    EncodeAES = lambda c, s: base64.b64encode(c.encrypt(pad(s)))
    DecodeAES = lambda c, e: c.decrypt(base64.b64decode(e)).rstrip(PADDING)

    secret = '01234567890123456789012345678912'
    IV = 'wir&/>H54mgd9a";'

    cipher = AES.new(secret,AES.MODE_CFB,IV)

    if typ == 0:
        encoded = EncodeAES(cipher, hat)
        return encoded
    else:
        decoded = DecodeAES(cipher, hat)
        return decoded

客户端

if os.path.exists(df):
    print ' found the file '
    f = open(df, 'rb')
    packet = f.read(1024)
    while packet != '':
        s.send(AESENC(packet,0)) 
        s.send(   AESENC('123XXX',0)  ) 
    s.send('123XXX')
    f.close()

服务器端

f = open('/root/Desktop/Transfer.mp3','wb')
while True:
    bits =  AESENC ( conn.recv(1024) , 1 )
    while (bits):
        f.write(bits)
        bits =  AESENC ( conn.recv(1024) , 1 )
        if bits.endswith('123XXX'):
            print '[+] Transfer completed '
            break

    f.close()
    break
return

有人知道如何解决这个问题吗?

1 个答案:

答案 0 :(得分:4)

对您对示例代码的误解表示歉意,并感谢您添加服务器和客户端调用!

请注意,您收到的错误消息与加密无关。您可以阅读base64.py库的相关部分:错误消息指示base64数据无效。特别是,它最后没有正确填充。

使用额外的呼叫站点信息,我认为问题是您正在加密,然后单独编码客户端上的每个1024字节数据块。然后,在服务器上,您正在从网络读取1024个字节并尝试解码它。但是,base64编码会增加原始数据的长度,因此您将读取的只是编码格式的前1024个字节,这将是截断的base64消息(因此填充不当)。

至于如何解决它,需要将base64消息全部解码为一个整体。因此,您需要计算从网络读取多少数据以获得完整的编码块(除了可能短的最后一个数据包之外,您可以可靠地进行计算,因为base64长度始终是(长度+ 2)/ 3 * 4),一次编码整个数据流(如果你想处理任意大小的文件,这可能是由于内存使用的问题),或定义你的网络协议,以便服务器可以告诉它看到一个完整的块可以用base64解码。