2011-05-19 119 views
5

我一直在试图写一个小文件服务器。我知道它的文件传输很好,但现在我试图添加加密奇怪的事情正在发生。我试图使用密码输入/输出流来使用DES加密来发送文件。该文件似乎完全由服务器传输,但我无法让客户端正确接收它。Java通过套接字发送加密文件

无论我传输什么类型的文件,客户端都不会离开我用来接收文件的循环。即使如此,我已经设法接收.pdf和.doc文件,这两个文件都没有任何错误,并且完全打开。当我发送图像时,最终似乎没有正确地通过。图像打开,但最终不会显示,只是灰色的区域。

我认为这些问题是相关的,但我不知道如何解决它们。

这里是我用来发送服务器端的文件中的代码:

Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding"); 
cipher.init(Cipher.ENCRYPT_MODE, publicKey); 
CipherOutputStream cipherOut = new CipherOutputStream(outToClient, cipher); 
byte[] fileBuffer = new byte[BUFFER_SIZE]; 
InputStream fileReader = new BufferedInputStream(new FileInputStream(aFile)); 
int bytesRead; 
while((bytesRead = fileReader.read(fileBuffer)) != EOF){ 
    cipherOut.write(fileBuffer, 0, bytesRead); 
} 
cipherOut.flush(); 

和代码接受它在客户端:

Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding"); 
cipher.init(Cipher.DECRYPT_MODE, serverPublicKey); 
CipherInputStream cipherIn = new CipherInputStream(inFromServer, cipher); 

byte[] fileBuffer = new byte[BUFFER_SIZE]; 
FileOutputStream fileWriter = new FileOutputStream(newFileName); 
int bytesRead; 
while((bytesRead = cipherIn.read(fileBuffer)) != EOF){ 
    fileWriter.write(fileBuffer, 0, bytesRead); 
} 
fileWriter.flush(); 
fileWriter.close(); 

在右边的指针方向会超级。

+4

正如一个附注,DES是一种**对称加密算法**,也就是说,在处理时没有**公钥**(或私钥)的概念DES。变量的名称“publicKey”和“serverPublicKey”具有误导性,因为它们实际上代表**共享密钥**。 – 2011-05-19 00:16:41

+0

您不关闭输出流服务器端。是EOF -1或0它应该是-1 – 2011-05-19 00:26:10

回答

2
while((bytesRead = cipherIn.read(fileBuffer)) != EOF){ 

只是要坚持读书,直到“bytesRead”的数量给你EOF,但是这不会发生,因为你没有关闭套接字(至少不是我能,如果你的代码中看到的)另一端。

我看到

cipherOut.flush() ; 

但是这不会关闭套接字。如果它只是'超出范围',它将不会被关闭,直到垃圾收集器收回对象。

+0

我看到你接受了这个答案,但关闭套接字并不是必要的,这不是最好的解决方案。 – jedwards 2011-05-19 01:00:51

+1

同意,但问题是,“什么不工作?”而不是“如何做到这一点?” – Andrew 2011-05-19 01:22:57

+0

@jdedwards接收器读取EOS时需要。可以通过长度字前缀或其他重叠协议来避免这两种情况。但考虑到现有的客户端代码,关闭是必要的。 – EJP 2013-05-02 21:57:21

2

你不要关闭CipherOutputStream服务器端

与块cyphers冲洗可能会导致某些字节不被发送,直到块被填充或执行紧密,这将导致填充进来效果将允许接收者找到EOF