Java: StreamCorruptedException occur when Decrypt object with DES

牧云@^-^@ 提交于 2020-01-09 10:32:33

问题


I have two method for Encrypt-save and decrypt-load Object from file in Android Internal Storage.

Encrypt and save process is done without any problem, but when I want to load the object StreamCorruptedException occurs in inputStream = new ObjectInputStream(cipherInputStream);

I searched SO more and more but I did't find a solution for my problem. all other solutions are for socket life or like this.

my code is below:

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

save method: (work well)

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 method: (can't load object from 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 methods for save and load:

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

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

}

回答1:


You're making at least two major mistakes.

  1. You have to use the same key to decrypt as you used to encrypt. You can't just generate a random key and except it to be able to decrypt anything. Cryptology isn't magic. You will have to arrange for the decryption key to be preserved somehow, transmitted if necessary, securely, and used at the decryption step.

  2. You're encrypting once with the SealedObject and again with the CipherOutputStream; then in the reverse direction you're decrypting once with the CipherInputStream and again via the SealedObject. This won't actually work, because the Cipher object isn't in comparable states at sender and receiver, and in any case it's pointless. Lose either the SealedObject or the Cipher streams.



来源:https://stackoverflow.com/questions/24600721/java-streamcorruptedexception-occur-when-decrypt-object-with-des

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!