如何使用流密码加密TCP数据?

时间:2017-12-03 05:51:55

标签: networking encryption cryptography stream-cipher

我尝试在我的网络软件中使用chacha20加密,但我遇到了问题

如果我加密4字节数据:服务器上的0x01 0x02 0x03 0x04

获取密文:0xd2 0xd3 0xc4 0xd5,然后将其发送给客户端

客户端可能一次收到< = 4bytes

如果客户端最初只收回0xd2 0xd3

它可以正确解密数据并获得明文0x01 0x02

但是当客户端收回最后2个字节0xc4 0xd5

似乎无法使用相同的随机数和密钥来解密数据

有没有办法解决问题

在发送之前将长度数据添加为前缀是一种解决方案,但它很奇怪,因为我正在使用流密码。

2 个答案:

答案 0 :(得分:3)

不是重新启动ChaCha20密码实例(或者更一般地说, context ),而是应该保持活着。

大多数加密API都允许您执行零碎的加密/解密。这通常意味着为第一部分和第二部分调用update方法,通常在检测到明文/密文的末尾时使用final方法。根据API,您应该期望每种方法的输出。

只有当您的API不允许您正确处理流时,您才应该聚合密文并在完整的密文上执行解密。

答案 1 :(得分:1)

ChaCha20使用密钥和随机数生成流。让(S0, S1, S2, S3)表示流的第一个字节,(M0, M1, M2, M3)表示邮件的前4个字节。

密文将计算为(M0⊕S0, M1⊕S1, M2⊕S2, M3⊕S3)。如果您有M0...M3随时可用,

如果您使用相同的密钥和随机数加密(M0, M1)然后(M2, M3),则最终会得到(M0⊕S0, M1⊕S1)(M2⊕S0, M3⊕S1)。使用(C0⊕S0, C1⊕S1, C2⊕S2, C3⊕S3)无法解密。

更糟糕的是,由于S0S1已被重复使用不同的消息,攻击者可以通过任何消息恢复它们。

为避免这种情况,最简单的方法是缓冲数据,直到达到块大小,然后加密整个块,而不是尝试加密部分块。