2017-08-30 47 views
0

最近我试图用Python Twisted设计物联网设备的自定义协议。由于大多数物联网设备(终端节点)的功能不足以支持TLS,因此我必须实施经过修改的轻量级传输安全性。但是,与standrad TLS相同,AES128/256用于数据加密。我应该使用AES加密的TCP流实现数据包分隔符吗?

众所周知,TCP是一个流,并且传递的消息可能需要在TCP流中分隔符。在面向文本的消息如HTTP/FTP中,使用\ n \ r。在二进制消息中,我们应该定义自己的结构,如TLV,V代表有效载荷数据。这可以通过Java中的Netty,Python中的Twisted实现。

当TCP被加密时,情况变得复杂。理论上,纯文本应该用AES加密,然后在TCP流上进行。文本消息很容易,但是在二进制消息中,类型/长度字段也被加密。此外,AES是面向块的算法,这意味着消息可能需要下一条消息来进行加密/解密。尽管AES可以是透明传输,但是对于二进制消息分片和解析来说很难实现。还有另一种方法,我们可以将TLV中的TL字段保留为纯文本,同时保持AES加密的V加密。但它只适用于二进制数据。并且它也需要AES中的填充。

是否有任何建议或参考,包括代码或项目?谢谢!

回答

0

AES是一种分组密码,因此以区块大小的块读取数据。在发送端,您的AES加密代码应该根据需要添加填充,它应该是AES实现的一部分。 (我会建议你在这个应用程序中使用AES-CBC)。在发射器上,只需以块大小的块读取数据。

在java中,我会从我的套接字使用DataInputStream,并执行readFully()。

Socket socket; 
DataInputStream ins = new DataInputStream(socket.getInputStream()); 

while(connectionOpen) { 
    byte[] aes = new Byte[blockSize]; 
    ins.readFully(aes); 
    //Decrypt received data aes 
    ... 
} 

由于您使用上面的readFully(),因此您确保始终接收正确大小(即块大小)的数据。

+0

以块大小的倍数读取数据并仅填充最后一个块。 – zaph

+0

现在,我明白了。与AES,事情变得更加简单。接收器只是读取块大小的块(如16B/32B)。而填充方法甚至可以帮助接收者分割数据包流! –