2011-05-19 60 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