getOutputSize恒定性? 我需要在TCP(从java到C++程序的块)中加密和发送数据(从100字节到每秒100兆字节),并且需要提前发送数据的大小,这样接收方知道什么时候停止读取当前消息并处理它,然后等待下一条消息。(连接保持打开状态,因此没有其他方法指示消息结束;因为数据可以是二进制的,我不能使用标志指示消息结束,因为加密的字节可能会随机地与我在某个点选择的任何标志相同)

getOutputSize恒定性? 我需要在TCP(从java到C++程序的块)中加密和发送数据(从100字节到每秒100兆字节),并且需要提前发送数据的大小,这样接收方知道什么时候停止读取当前消息并处理它,然后等待下一条消息。(连接保持打开状态,因此没有其他方法指示消息结束;因为数据可以是二进制的,我不能使用标志指示消息结束,因为加密的字节可能会随机地与我在某个点选择的任何标志相同),java,encryption,networking,Java,Encryption,Networking,我的问题是在加密之前计算加密消息的大小,由于填充等原因,它通常与输入长度不同 假设我已初始化如下: AlgorithmParameterSpec paramSpec = new IvParameterSpec(initv); encipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); mac = Mac.getInstance("HmacSHA512"); encipher.init(Cipher.ENCRYPT_MODE, key, param

我的问题是在加密之前计算加密消息的大小,由于填充等原因,它通常与输入长度不同

假设我已初始化如下:

AlgorithmParameterSpec paramSpec = new IvParameterSpec(initv);
encipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
mac = Mac.getInstance("HmacSHA512");
encipher.init(Cipher.ENCRYPT_MODE, key, paramSpec);
mac.init(key);
buf = new byte[encipher.getOutputSize(blockSize)];
然后我发送数据(还有一个类似的函数,它使用一个流作为输入,而不是
byte[]
):

但是如何预先计算将发送到接收计算机的输出大小呢? 基本上,我想在循环之前输出.writeInt(messageSize)。但是如何计算messageSize呢?Cipher的
getOutputSize()
文档中说,“此调用考虑了来自上一次更新调用的任何未处理(缓冲)数据,以及填充。”因此,这似乎意味着在多次调用
update()
doFinal()时,同一函数参数的值可能会改变
…如果
blockSize
是AES CBC块大小的倍数以避免填充,我可以假设每个块都有一个常量值吗?也就是说,只需检查
\u blockSize%encipher.getOutputSize(1)!=0
,然后在write函数中

int messageSize = (input.length / blockSize) * encipher.getOutputSize(blockSize) +                     
                  encipher.getOutputSize(input.length % blockSize + mac.getMacLength());
?


如果没有,我有什么选择?

使用PKCS5填充时,填充后的消息大小将为:

padded_size = original_size + BLOCKSIZE - (original_size % BLOCKSIZE);


上面给出了整个消息的完整大小(直到
doFinal()
调用),给定了输入消息的完整大小。我突然想到,您实际上只想知道最后部分的长度-您只需要存储
doFinal()
调用的输出字节数组,并使用
.length()
该数组上的方法。

您只是猜测、修补、祈祷。使用SSL/TLS。Java的JSSE对SSL有易于使用的支持。Greg,我不能这样做,因为系统必须是对称的,仅限私钥——公钥身份验证/密钥交换。当前的Java实现不支持这一点。嗨,caf,我假设BLOCKSIZE是任何Cipher.getBlocksize()返回?谢谢(对于AES,这应该是16)。
padded_size = original_size + BLOCKSIZE - (original_size % BLOCKSIZE);