2014-07-06 26 views
0

我有兩種方法用於Android內部存儲中的文件的加密保存和解密加載對象。Java:當使用DES解密對象時發生StreamCorruptedException

加密和保存過程中沒有任何問題做了,但是當我想要加載StreamCorruptedException發生對象inputStream = new ObjectInputStream(cipherInputStream);

我搜索所以越來越多,但餘did't找到我的問題的解決方案。所有其他解決方案都適用於套接字生命或者像這樣

我的代碼如下:

private static byte[] iv = { (byte) 0xB1, (byte) 0x15, (byte) 0xB5, 
     (byte) 0xB7, (byte) 0x66, (byte) 0x43, (byte) 0x2F, (byte) 0xA4, 
     (byte) 0xB1, (byte) 0x15, (byte) 0x35, (byte) 0xC7, (byte) 0x66, 
     (byte) 0x58, (byte) 0x2F, (byte) 0x5F }; 

保存方法:(工作孔)

private static String saveToFile(Serializable object, String fileName, 
     Context ctx) { 
    try { 
     Cipher cipher = null; 
     cipher = Cipher.getInstance("DES"); 
     SecretKey key = KeyGenerator.getInstance("DES").generateKey(); 
     AlgorithmParameterSpec paramSpec = new IvParameterSpec(iv); 

     cipher.init(Cipher.ENCRYPT_MODE, key, paramSpec); 
     SealedObject sealedObject = null; 
     sealedObject = new SealedObject(object, cipher); 
     CipherOutputStream cipherOutputStream = null; 

     FileOutputStream fos = ctx.openFileOutput(fileName, 
       Context.MODE_PRIVATE); 
     cipherOutputStream = new CipherOutputStream(
       new BufferedOutputStream(fos), cipher); 
     ObjectOutputStream outputStream = null; 
     outputStream = new ObjectOutputStream(cipherOutputStream); 
     outputStream.writeObject(sealedObject); 
     outputStream.close(); 

     return "Save Complete!"; 

    } catch (IOException e) { 
     e.printStackTrace(); 
     return e.getMessage(); 
    } catch (NoSuchAlgorithmException e) { 
     e.printStackTrace(); 
     return e.getMessage(); 
    } catch (NoSuchPaddingException e) { 
     e.printStackTrace(); 
     return e.getMessage(); 
    } catch (InvalidKeyException e) { 
     e.printStackTrace(); 
     return e.getMessage(); 
    } catch (IllegalBlockSizeException e) { 
     e.printStackTrace(); 
     return e.getMessage(); 
    } catch (InvalidAlgorithmParameterException e) { 
     e.printStackTrace(); 
     return e.getMessage(); 
    } 
} 

Load方法:(不能從cipherInputStream加載對象)

private static Serializable loadFromFile(String fileName, Context ctx) { 
    Cipher cipher = null; 
    Serializable userList = null; 
    try { 
     cipher = Cipher.getInstance("DES"); 

     // Code to write your object to file 
     SecretKey key = KeyGenerator.getInstance("DES").generateKey(); 
     AlgorithmParameterSpec paramSpec = new IvParameterSpec(iv); 

     cipher.init(Cipher.DECRYPT_MODE, key, paramSpec); 
     CipherInputStream cipherInputStream = null; 

     FileInputStream fos = ctx.openFileInput(fileName); 
     cipherInputStream = new CipherInputStream(new BufferedInputStream(
       fos), cipher); 

     ObjectInputStream inputStream = null; 
     inputStream = new ObjectInputStream(cipherInputStream); 
     // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 
     SealedObject sealedObject = null; 
     sealedObject = (SealedObject) inputStream.readObject(); 
     userList = (Serializable) sealedObject.getObject(cipher); 
     inputStream.close(); 
    } catch (NoSuchAlgorithmException e) { 
     e.printStackTrace(); 
     return e.getMessage(); 
    } catch (NoSuchPaddingException e) { 
     e.printStackTrace(); 
     return e.getMessage(); 
    } catch (InvalidKeyException e) { 
     e.printStackTrace(); 
     return e.getMessage(); 
    } catch (InvalidAlgorithmParameterException e) { 
     e.printStackTrace(); 
     return e.getMessage(); 
    } catch (FileNotFoundException e) { 
     e.printStackTrace(); 
     return e.getMessage(); 
    } catch (StreamCorruptedException e) { 
     e.printStackTrace(); 
     return e.getMessage(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
     return e.getMessage(); 
    } catch (ClassNotFoundException e) { 
     e.printStackTrace(); 
     return e.getMessage(); 
    } catch (IllegalBlockSizeException e) { 
     e.printStackTrace(); 
     return e.getMessage(); 
    } catch (BadPaddingException e) { 
     e.printStackTrace(); 
     return e.getMessage(); 
    } 
    return userList; 
} 

公共保存和加載方法:

public Serializable loadPlayer(Context ctx) { 
    return loadFromFile("player.dat", ctx); 
} 

public String savePlayer(Player player, Context ctx) { 
    return saveToFile(player, "player.dat", ctx); 

} 
+0

您是否在每次使用保存或加載方法時生成新的隨機密鑰? – jarnbjo

+3

根據@jarnbjo評論,您必須使用與您加密相同的密鑰進行解密。目前您的解密代碼會生成自己的密鑰。 *不能*工作。 –

+1

你爲什麼要加密兩次?你知道嗎?你正在加密兩次?擺脫SealedObject或Cipher流。 – EJP

回答

0

你至少犯了兩個重大錯誤。

  1. 您必須使用與您用於加密時相同的密鑰進行解密。你不能只是生成一個隨機密鑰,除非它能夠解密任何東西。密碼學不是魔術。您必須安排解密密鑰以某種方式得到保留,必要時傳輸,安全,並在解密步驟中使用。

  2. 您正在使用SealedObject再次使用CipherOutputStream加密一次;然後在相反的方向上,您使用CipherInputStream並再次通過SealedObject解密一次。這實際上並不起作用,因爲Cipher對象在發送者和接收者中不處於可比較的狀態,並且在任何情況下都沒有意義。丟失SealedObject或Cipher流。

相關問題