- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我需要通过 TCP 加密和发送数据(每条消息从几百字节到几百兆字节)以 block 从 Java 到 C++ 程序,并且需要发送的大小提前发送数据,以便收件人知道何时停止读取当前消息并处理它,然后等待下一条消息(连接保持打开状态,因此没有其他方式指示消息结束;因为数据可以是二进制的,我可以由于加密字节可能随机碰巧与我在某个时候选择的任何标志相同,所以不要使用标志来指示消息结束)。
我的问题是在加密之前计算加密消息的大小,由于填充等原因,这通常与输入长度不同。
假设我已经初始化如下:
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[]
):
public void writeBytes(DataOutputStream out, byte[] input) {
try {
//mac.reset(); // Needed ?
int left = input.length;
int offset = 0;
while (left > 0)
{
int chunk = Math.min(left, blockSize);
int ctLength = encipher.update(input, offset, chunk, buf, 0);
mac.update(input, offset, chunk);
out.write(buf, 0, ctLength);
left -= chunk;
offset += chunk;
}
out.write(encipher.doFinal(mac.doFinal());
out.flush();
} catch (Exception e) {
e.printStackTrace();
}
}
但是如何预先计算将发送到接收计算机的输出大小呢?基本上,我想在循环之前 out.writeInt(messageSize) 。但是如何计算messageSize呢? Cipher 的 getOutputSize()
文档说“此调用考虑了来自先前更新调用和填充的任何未处理(缓冲)数据。”所以这似乎意味着,对于 update()
或 doFinal()
的多次调用,同一个函数参数的值可能会改变......我可以假设如果 blockSize
是 AES CBC block 大小的倍数以避免填充,我应该为每个 block 设置一个常量值?也就是说,只需检查 _blockSize % encipher.getOutputSize(1) != 0
然后在写入函数中,
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()
方法。
关于java - getOutputSize 恒定?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2367697/
我需要通过 TCP 加密和发送数据(每条消息从几百字节到几百兆字节)以 block 从 Java 到 C++ 程序,并且需要发送的大小提前发送数据,以便收件人知道何时停止读取当前消息并处理它,然后等待
我正在尝试解密使用 AES256 CBC 加密的文件,这是我的代码: PaddedBufferedBlockCipher cipher = new PaddedBufferedBlockCipher(
我在使用 Bouncy caSTLe 的 Aes 中使用解密功能时遇到问题。 我有一个常规的加密/解密函数,但是速度太慢了。现在,我正在尝试使用 BouncyCaSTLe 库中测试文件示例的部分代码来
我是一名优秀的程序员,十分优秀!