Java:使用DES的Decrypt对象时发生StreamCorruptedException

时间:2014-07-06 22:02:28

标签: java android encryption des

我有两种方法可以在Android内部存储中从文件加密保存和解密加载对象。

加密和保存过程没有任何问题,但是当我想加载StreamCorruptedException

中出现的对象inputStream = new ObjectInputStream(cipherInputStream);

我搜索越来越多,但我找不到解决问题的方法。所有其他解决方案都适用于插座寿命或类似情况。

我的代码如下:

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();
    }
}

加载方法:(无法从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);

}

1 个答案:

答案 0 :(得分:0)

你至少犯了两个重大错误。

  1. 您必须使用相同的密钥进行解密,就像您以前加密一样。你不能只生成一个随机密钥,除了它可以解密任何东西。密码学并不神奇。您必须安排以某种方式保存解密密钥,必要时进行传输,安全,并在解密步骤中使用。

  2. 您使用SealedObject加密一次,再使用CipherOutputStream加密;然后反方向你用CipherInputStreamSealedObject再解密一次。这实际上不起作用,因为Cipher对象在发送方和接收方处不具有可比较的状态,并且无论如何它都没有意义。丢失SealedObject或Cipher流。