2013-05-06 100 views
1

我想序列化一個對象(在這種情況下是一個簡單的字符串),加密它,並將其寫入文件。加密似乎可行,但解密總是失敗。我試着摸索,但我似乎無法找出我在做什麼錯..使用DES加密和解密Java文件

// Create a new key to encrypt and decrypt the file 
byte[] key = "password".getBytes(); 

// Get a cipher object in encrypt mode 
Cipher cipher = null; 
try { 
    DESKeySpec dks = new DESKeySpec(key); 
    SecretKeyFactory skf = SecretKeyFactory.getInstance("DES"); 
    SecretKey desKey = skf.generateSecret(dks); 
    cipher = Cipher.getInstance("DES"); 
    cipher.init(Cipher.ENCRYPT_MODE, desKey); 
} catch (InvalidKeyException | NoSuchAlgorithmException | InvalidKeySpecException | NoSuchPaddingException ex) { 
    System.err.println("[CRITICAL] Incryption chiper error"); 
} 

// Encrypt the file 
try { 
    new ObjectOutputStream(new CipherOutputStream(new FileOutputStream("test"), cipher)).writeObject("test text"); 
} catch (IOException e) { 
    System.err.println("[CRITICAL] Error encrypting data: " + e.getMessage()); 
    e.printStackTrace(); 
} 

// Get a cipher object in decrypt mode 
try { 
    DESKeySpec dks = new DESKeySpec(key); 
    SecretKeyFactory skf = SecretKeyFactory.getInstance("DES"); 
    SecretKey desKey = skf.generateSecret(dks); 
    cipher = Cipher.getInstance("DES"); 
    cipher.init(Cipher.DECRYPT_MODE, desKey); 
} catch (InvalidKeyException | NoSuchAlgorithmException | InvalidKeySpecException | NoSuchPaddingException ex) { 
    System.err.println("[CRITICAL] Incryption chiper error"); 
} 

// Decrypt the file 
try { 
    // This is the line that throws the exception 
    System.out.println((String) new ObjectInputStream(new CipherInputStream(new FileInputStream("test"), cipher)).readObject()); 
} catch (IOException | ClassNotFoundException e) { 
    System.err.println("[CRITICAL] Error decrypting data: " + e.getMessage()); 
    e.printStackTrace(); 
} 

以下異常運行上面的代碼的結果:

[CRITICAL] Error decrypting data: null 
java.io.EOFException 
at java.io.ObjectInputStream$PeekInputStream.readFully(ObjectInputStream.java:2304) 
at java.io.ObjectInputStream$BlockDataInputStream.readUTFBody(ObjectInputStream.java:3042) 
at java.io.ObjectInputStream$BlockDataInputStream.readUTF(ObjectInputStream.java:2843) 
at java.io.ObjectInputStream.readString(ObjectInputStream.java:1617) 
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1338) 
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:369) 
at Server.DataPersistence.main(DataPersistence.java:203) 

有誰有什麼想法?

謝謝!

回答

5

我的猜測是,當您嘗試打開並重新讀取數據返回到您的程序時,沒有任何內容寫入文件。在嘗試再次讀取文件之前,嘗試在輸出流上調用flush();然後close();

+0

+1。在這種情況下(CipherStream),它需要是'close()'。否則數據將不完整。 – Thilo 2013-05-06 00:36:27

+0

謝謝!在對象的outputStream上調用'flush()',然後'close()'做到了訣竅!我假設它遞歸地關閉所有其他流? – rthur 2013-05-06 08:25:41

+0

java中的流遵循裝飾模式。在最外層流上進行的調用通過在每層停止的組合對象結構向下傳播,以完成裝飾器可能需要爲該調用執行的任何操作,然後結束到最低層。 – cmbaxter 2013-05-06 10:45:50