Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java:通过套接字加密的数据_Java_Sockets_Encryption_Cryptography - Fatal编程技术网

Java:通过套接字加密的数据

Java:通过套接字加密的数据,java,sockets,encryption,cryptography,Java,Sockets,Encryption,Cryptography,我正试图通过套接字发送加密数据 我构建了一个服务器和一个客户机,我可以成功地与一个典型的服务器交换数据(这是一个客户机示例,在服务器上也是如此): 我还有一个方法,它接受一个字节[]和一个密钥,并返回一个用AES 128位加密的字节[]。另一种方法以相同的方式解密 现在,我如何通过套接字发送加密数据? 我遇到了很多问题,因为加密缓冲区的大小与普通缓冲区不同。例如,我从文件中加载4096字节,对它们进行加密,最后得到4112。 这个数字对于转移来说不是最优的。我无法将其分解,因为服务器显然需要读取

我正试图通过套接字发送加密数据

我构建了一个服务器和一个客户机,我可以成功地与一个典型的服务器交换数据(这是一个客户机示例,在服务器上也是如此):

我还有一个方法,它接受一个
字节[]
和一个密钥,并返回一个用AES 128位加密的
字节[]
。另一种方法以相同的方式解密

现在,我如何通过
套接字
发送加密数据? 我遇到了很多问题,因为加密缓冲区的大小与普通缓冲区不同。例如,我从文件中加载
4096
字节,对它们进行加密,最后得到
4112
。 这个数字对于转移来说不是最优的。我无法将其分解,因为服务器显然需要读取“整个”数据块(因为它们是加密的),否则它将无法解密

即使我先加密整个文件,然后发送它,我仍然需要一块一块地加密它,当我读回来解密它时,这些块会被分解

显然,服务器无法知道加密块的填充大小(在接收任何内容之前),因此它总是一次读取4096字节


我能做些什么?

如果你打算以4096字节的块发送数据,你可以只读取稍小的块(可能是4095字节,如果你的填充方式和我想的一样),然后通过网络发送你的填充4096字节的块

的确,未加密的明文和加密的密文的大小是不一样的,但是加密任意两个等长的明文会产生等长的密文。如果始终加密相同大小的明文,则通过套接字发送的加密密文的大小应始终相同。因此,作为上述方法的替代方法,您可以继续以4096块的形式读取文件,并告诉接收缓冲区需要4112字节

你没有提到你正在使用哪种AES模式(我怀疑是CBC)或者你正在使用哪种填充方案(我怀疑是PKCS#7),所以我不确定填充在你的方案中是如何工作的,但我猜你的方案正在被填充到下一个16字节的倍数(如果已经是16的倍数,则会添加完整的16字节)。因此,您应该能够读取4095字节的文件块,或者最坏的4080字节,它们将被填充到4096字节

我还鼓励您切换到GCM模式,它(1)不需要填充,(2)除了加密之外还提供身份验证

我能做什么


你什么都不用做。无论您发送什么,TCP都将对其进行分段,IP将以其喜欢的任何方式对其进行打包。在接收端,TCP是字节流,而不是消息传递系统。

您所说的“传输的最佳数量”是什么意思?请指定有效负载大小。您的服务器可以根据需要调整缓冲区,或者只需读取多个
0-4096
块,直到获得整个负载。
4096
是一次读取可以读取的数据量,这并不意味着所有有效负载都必须在该范围内。请查看
CipherInputStream
CipherOutputStream
。不要在循环内冲洗。注意“传输不理想”是错误的。TCP将以它喜欢的任何方式分割数据。不要担心试图超越TCP。你不需要。@AJNeufeld,您不需要
DataOutputStream
来实现
OutputStream.write()
已经可以这样做了,因为任何输出流。GCM都不会加密,但JCA API会将authtag附加到密文中,从而有效地扩展密文。CBC通常要求您将IV与密文一起发送,而GCM可以使用不需要传输的计数器,前提是您的数据传输像TCP一样有序且可靠,而不是UDP。
int count = 0;
byte[] buffer = new buffer[4096];

while ((count = fileInputStream.read(buffer)) >= 0) 
{
    outToServer.write(buffer, 0, count);
    outToServer.flush();
}